Skip to content

JosephTLyons/andromeda

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

andromeda

Quickly create large amounts of unique licenses. Heavily inspired by random code generator.

Creating Unique Licenses

Making a batch of unique licenses is very simple. Run the script with:

python3 main.py

Let's go ahead and create 1000 licenses. We want the licenses to be 20 symbols long and we want to include numbers, uppercase letters, and lowercase letters, but not symbols:

File Options
============
File extension (keep blank for txt):

Batch Options
=============
Number of licenses: 1000
License separator character (keep blank for newline):

License Characteristics Options
===============================
License length: 20
Enter 'y' to use numbers: y
Enter 'y' to use uppercase letters: y
Enter 'y' to use lowercase letters: y
Enter 'y' to use symbols: n

Results
=======
File path: /Users/josephlyons/Programming/Python/andromeda/src/1000_unique_licenses.txt
Requested number of licenses: 1000
Total possible number of licenses given current inputs: 62^20 = 704423425546998022968330264616370176
License pool coverage: (1000 / (62^20)) * 100 = 1.4196007170310687e-31%

When we are done, we will find a new file within the same folder as this script named 1000_unique_licenses.txt. Opening the file, we see:

dPzu8znblSPF1rmy4coW
djKD1ZxNLqAAo6ah6ZuA
dCZbvdHO9KIvm3CAnNCE
dzfN89poHQ7QMxZgGKH1
dqnj4G4A3mh23SpeoaZG
drsWemJsfg6aCzw0wHge
dYGS8jevEv5T0PFnd1bZ
dDSR4ZrQ2JgVZT2GmV4t
doO2eKULC3JLfuWBhQys
dp5yr9w1PrPpuAIWcGMH
dgFnW1Eppccc5gRNEFAR
dWosgmKFvdFtbKvCDB5X
dyTmrjnIhLK1pwhmXr9V
dMJQWVxqxRSjyt5lIOey
dwbPgKHTq5frkOzHJ0wP
dFheZibfSFeXVlPfzeSg
...

How it Works

  1. Check to make sure that it is possible to create the amount of unique licenses requested based on the the license length and character set. For example, if the user requests 1,000,000 unique licenses, but only asks for licenses of length 4 and wants only numbers as characters, it will not be possible, as 10^4 < 1,000,000. We must have more possible combinations than the number of licenses requested in order to ensure all licenses will be unique.
  2. Make a characterList that is comprised of all the symbols the user wishes to use in their licenses (numbers, lowercase letters, uppercase letters, and symbols).
  3. Shuffle this list and push a copy of it into another list, called listOfCharacterLists. This step is executed as many times as the length of the license requested.
  4. Create a new list of numbers called index_list. Each cell in this list holds an index that corresponds to a characterList in the listOfCharacterLists.
  5. A license is generated by using the index_list to provide an index to each of the corresponding internal characterLists in listOfCharacterLists. The listOfCharacterLists contains as many internal characterLists as the length of our license. This can be seen sort of as a speedometer that starts with 0000 miles. As we roll through the miles in the rightmost column, it resets back to zero and the next value to the left increments by 1. This is exactly how the index_list and listOfCharacterLists work to obtain licenses.

In order to avoid printing licenses that look like this:

PWZdySrxntWyBxYYZAlT
PWZdySrxntWyBxYYZAlB
PWZdySrxntWyBxYYZAlZ
PWZdySrxntWyBxYYZAlJ
...

we need to pull licenses evenly over the entire spectrum of possible combinations. We can do this by taking the total possible combinations based on the user settings and dividing it by the number of licenses needed. This will give us the value that we need to be apply to the index_list before printing the next license to the file.

Using the example from earlier, our licenses are of length 20 and use 62 types of symbols (10 numbers + 26 lowercase letters + 26 uppercase letters). We have 62^20 possible unique license combinations. Because we want 1000 licenses, the spacing between licenses to be printed to the file is (62^20) / 1000 = 7.04423425546998e+32. If we set n = 7.04423425546998e+32, then the function increaseIndexVectorBy() efficiently applies this number to the index_list in roughly log(n) with base 62 operations. Using this method, we are able to print licenses that are equally spaced apart in the total combination space, as shown in the first sample output earlier.

We can even print all of the values of the index_list to the terminal to see the patterns better by uncommenting print(self.index_list.get_index_string()):

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 03 52 20 20 51 36 12 55 34 13 55 03 29 16 22 50 36 43 40
00 07 42 40 41 41 10 25 49 06 27 48 06 58 32 45 39 11 25 18
00 11 32 61 00 30 46 38 42 40 41 41 10 25 49 06 27 48 06 58
00 15 23 19 21 20 20 51 36 12 55 34 13 55 03 29 16 22 50 36
00 19 13 39 42 09 57 02 29 47 07 27 17 22 19 52 04 59 32 14
00 23 03 60 00 61 31 15 23 19 21 20 20 51 36 12 55 34 13 54
00 26 56 18 21 51 05 28 16 53 35 13 24 18 52 35 44 08 57 32
00 30 46 38 42 40 41 41 10 25 49 06 27 48 06 58 32 45 39 10
00 34 36 59 01 30 15 54 03 60 00 61 31 15 23 19 21 20 20 50
00 38 27 17 22 19 52 04 59 32 14 54 34 44 39 42 09 57 02 28
00 42 17 37 43 09 26 17 53 04 28 47 38 11 56 02 60 31 46 06
00 46 07 58 01 61 00 30 46 38 42 40 41 41 10 25 49 06 27 46
00 49 60 16 22 50 36 43 40 10 56 33 45 08 26 48 37 43 09 24
00 53 50 36 43 40 10 56 33 45 08 26 48 37 43 09 26 17 53 02
00 57 40 57 02 29 47 07 27 17 22 19 52 04 59 32 14 54 34 42
...

File Customization

Andromeda allows you to pick you own file extension and the license separator character. This means you can build license files however you like. The previous example demonstrates the creation of a .txt file where the license separation character is a newline, resulting in each license being on its own line. You could also create a comma separated value file by specifying .csv as the file extension and , as the license separator character. It should be noted that if you choose a license separator character that is not a newline and the license separator character also exists in the character list you allow for generating licenses, it will be removed automatically from the character list; you do not want a license separator character showing up randomly in the middle of a license.

Pitfalls to be Aware of

Andromeda does not care if you choose settings that result in a very low pool of license combinations for it to pick from. You should be aware of this. Consider the following example:

File Options
============
File extension (keep blank for txt):

Batch Options
=============
Number of licenses: 1000
License separator character (keep blank for newline):

License Characteristics Options
===============================
License length: 4
Enter 'y' to use numbers: y
Enter 'y' to use uppercase letters: n
Enter 'y' to use lowercase letters: n
Enter 'y' to use symbols: n

Results
=======
File path: /Users/josephlyons/Programming/Python/andromeda/src/1000_unique_licenses.txt
Requested number of licenses: 1000
Total possible number of licenses given current inputs: 10^4 = 10000
License pool coverage: (1000 / (10^4)) * 100 = 10.0%

The output file produced will look something like this:

9444
9474
9494
9464
9484
9434
9424
9404
9414
9454
9244
9274
9294
9264
9284
9234
...

Notice that the licenses are fairly similar. Also, note that it would be fairly easy to randomly guess a license. The probability that a random guess would be an actual license is 1000 / (10^4) = 0.1. Andromeda tries to help the user by calculating and printing out the license pool coverage:

License pool coverage: (1000 / (10^4)) * 100 = 10.0%

but it is ultimately up to the user to understand what this means and adjust the settings to both increase the complexity of the output and decrease the chances of guessing a license. Using the example from earlier with 1000 licenses of length 20 using all symbols, the probability that a random guess would be an actual license is 1000 / (62^20) = 1.4196007e-33.

Releases

No releases published

Packages

No packages published

Languages