- it must be a unique string;
- line length should be 8 characters;
- It must contain 2 digits;
- All characters (non-digital characters) must be in upper case.
Assuming that:
- Requirements No. 2 and No. 3 are accurate (exactly 8 characters, exactly 2 digits), and not the minimum
- “characters” in requirement 4 are 26 capital letters A to Z
- you need a uniformly distributed random string
Then your proposed method has two problems. First, the letters A - Z are ASCII 65–90, not 64–89. Another is that it does not evenly distribute numbers within the possible string space. This can be fixed by following these steps:
- Create two different integers from 0 to 7 and sort them.
- Generate 2 random numbers from 0 to 9.
- Create 6 random letters from A to Z.
- Use two different integers in step # 1 as positions and put 2 numbers in these positions.
- Put 6 random letters in the remaining positions.
There are 28 possibilities for two different integers ((8 * 8 - 8 duplicates) / 2 orders), 26 6 possibilities for letters and 100 possibilities for numbers, the total number of # possible combinations: N comb = 864964172800 = 8.64 x 10 11 .
edit:. If you want to avoid the database for storage, but at the same time guarantee both the uniqueness of the lines and their cryptographic protection, the best choice is a cryptographically random bijection from the counter between 0 and N max <= N comb to a subset of the space of possible output lines. ( Bijection , which means that there is a one-to-one correspondence between the output line and the input counter.)
This is possible with Feistel networks , which are commonly used in hash functions and symmetric cryptography (including AES). You will probably want to select N max = 2 39 which is the greatest power of 2 <= N comb , and use the 39-bit Feistel network using the private key that you keep secret. Then you connect your counter to the Feistel network, and the output shows another 39-bit number X, which is then converted to the corresponding line as follows:
- Repeat the next step 6 times:
- Take X mod 26, generate an uppercase letter and set X = X / 26.
- Take X mod 100 to generate two digits and set X = X / 100.
- X will now be between 0 and 17 inclusive (2 39/26 6/100 = 17.796 ...). Match this number with two unique digit positions (it might be easiest to use a lookup table since we are only talking about 28 possibilities. If you had more, use the Floyd algorithm to create a unique permutation and use the base variable mod + integer divide method instead of generating a random number).
- Follow the random approach described above, but use the numbers generated by this algorithm instead.
Alternatively, use 40-bit numbers, and if your Feistel network output is> N comb , then increase the counter and try again. This covers the entire string space due to the rejection of invalid numbers and the need to re-execute the algorithm. (But you do not need a database for this.)
But this is not something to enter if you do not know what you are doing.
source share