0

I would like to generate a sequence of strings in the same format of digits and letters positions

e.g ABC12,DEV45,UED23,...

It's also required a formula to generate the next string from the current one. for example from the string above:

f(ABC12)=DEV45
f(DEV45)=UED23

I would like to use this to generate next "look-random" unique code in a defined format. What algorithm do you suggest? Thanks a lot.

2
  • what does unique in the problem means? Commented Aug 16, 2017 at 4:32
  • @Elveryx Which language are you using? Commented Sep 1, 2017 at 7:34

2 Answers 2

4

A code of the format "ABC12" is basically a 5-digit number where the first 3 digits are base-26 and the last 2 digits are decimal. There are 26×26×26×10×10 or 1,757,600 of these. Each code is easily converted to the corresponding number and back:

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z
0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
ABC12 = ((( 0 * 26 +  1) * 26 +  2) * 10 +  1) * 10 +  2 =     2,812
DEV45 = ((( 3 * 26 +  4) * 26 + 21) * 10 +  4) * 10 +  5 =   215,345
UED23 = (((20 * 26 +  4) * 26 +  3) * 10 +  2) * 10 +  3 = 1,362,723
    2,812 / 10 =     281 rem:  2
      281 / 10 =      28 rem:  1
       28 / 26 =       1 rem:  2
        1 / 26 =       0 rem:  1
        0 / 26 =       0 rem:  0  ->  0 1 2 1 2  ->  ABC12

  215,345 / 10 =  21,534 rem:  5
   21,534 / 10 =   2,153 rem:  4
    2,153 / 26 =      82 rem: 21
       82 / 26 =       3 rem:  4
        3 / 26 =       0 rem:  3  ->  3 4 21 4 5  ->  DEV45

1,362,723 / 10 = 136,272 rem:  3
  136,272 / 10 =  13,627 rem:  2
   13,627 / 26 =     524 rem:  3
      524 / 26 =      20 rem:  4
       20 / 26 =       0 rem: 20  ->  20 4 3 2 3  ->  UED23

To loop through the numbers from 0 to 1,757,599 in a pseudo-random way, choose a step size which only returns to zero after having gone through every number, and then calculate the next value as:

x -> (x + step) % 1,757,600

So step should have no common factors with 1,757,600:

1,757,600 = 2 * 2 * 2 * 2 * 2 * 5 * 5 * 13 * 13 * 13

and preferably be greater than 26*26*10*10 so that every digit changes with every step; so, e.g.:

step = 3^11 = 177,147

which gives this sequence:

   2,812                                       ABC12
(  2,812 + 177,147) % 1,757,600 = 179,959  ->  CRF59
(179,959 + 177,147) % 1,757,600 = 357,106  ->  FHJ06
                                               ...

Here's a code example to demonstrate the method. It's a bit fiddly because JavaScript. In C-like languages where a string is basically an array of integers, the code will be more straightforward.

function nextCode(current) {
    var base = [26,26,26,10,10], symbol = [65,65,65,48,48], char = [], number = 0;
    for (var i = 0; i < 5; i++) {
        var digit = current.charCodeAt(i) - symbol[i];
        number = number * base[i] + digit;
    }
    number = (number + 177147) % 1757600;
    for (var i = 4; i >= 0; i--) {
        var remainder = number % base[i];
        number = (number - remainder) / base[i];
        char[i] = String.fromCharCode(symbol[i] + remainder);
    }
    return char.join('');
}
document.write("ABC12 &rarr; " + nextCode("ABC12"));

Sign up to request clarification or add additional context in comments.

1 Comment

+1 You might mention this same principle can be made to work with multiplicative stepping (plus some mechanism to include AAA00 in the cycle) or, possibly, through some sort of perfect hashing function or pseudorandom number generator with sufficient cycle length.
0

One of the approaches is to precalculate letter part in an array form and then combine it with the consecutive numbers. For the letter array:

  1. start with AAA, AAB, AAC, ..., ABA, ABB, ..., ZZZ (total 17576 elements) -- all possible unique combinations;
  2. shuffle the array -- now they are in (a) random and (b) predictive order;
  3. from any given value -> use the next element from the array.

For the digit part, use simple counting:

  1. start with 00;
  2. from any given value -> increment by 1;
  3. if the result is 100, use the next letter part -- thus each string is unique.

This provides 1757600 unique strings like ABC12.

1 Comment

Thank you. Though I would like to make the next element look random rather than increment of the previous string. Also I do would not like to use a database of pre-generated strings. Just a formula that take input of the current string, and output thenext one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.