Incremental Alphanumeric String ID
Recently I came to a situation where I need to generate alpha-numeric string as an Id, with the below constraints
1. It should increment starting from a given string
2. It should first go to all the permutations within the given string length, but if it is still not enough, program should generate the next string
Here is the problem in brief
1. I will be given a alphanumeric string which can have any length. example : “AbCBC”
2. Program should generate the next string pattern. example : in my case it should be “AbCBD”
3. This should be a continuous process, so Until program is stopped it should continuously generate next alphanumeric String
Ok.. so when I first thought about this problem I was not able to figure how to approach so what I did was searching all throughout the internet for a source code like a typical programmer 🙂 but fortunately I was not able to find the code example so I had to write one by my self.
Here is my approach, which you will feel very simple at the end. Lets say you are ask to generate all the permutations up to number 999 starting from 100 only using numbers what will you do ?
now this is very easy you simply write a for loop starting from 100 up to 999 and inside of that you have your permutations. done……
now I’m asking you to generate all the possible alpha numeric Id’s that are starting from 0000 and ending in zzzz, also I say case matters, which means you can have “1zXx” as a Id in the middle and X and x are two different symbols.
here is a way of thinking this problem, when using numbers only, it automatically generate all permutations when counting, now numbers are just 10 symbols that goes 0 to 9 and which has base 10, what if I replace 1-9 with A-J, bye keeping the qualities of the numbers, so then “AAAA” + 1 becomes AAAB
Ok now you are getting something to your mind, keep thinking,
We all understand that alpha numeric means it has numbers + alphabet, so base 10 is not enough to represent it. In our case we have 10 numbers + 26 characters of simple alphabet + 26 characters of Capital Alphabet, all together 62, Ok then lets use 62 as our base and do calculations!!!
‘0’ , ‘1’ , ‘2’ , ‘3’ , ‘4’ , ‘5’ , ‘6’ , ‘7’ , ‘8’ , ‘9’,
‘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’ , ‘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’
So above is my number set it has 62 different symbols that represent 0-61, and for adding two numbers I take 62 as the base, let me explain the last part more simply,
according to my number set 61 is “z” so z+1 = 62 but since I say my base is 62 you can have only up to 61 which means according to my number set value is 10 (if you getting confused try to remember how you add two base 2 numbers ) if I disguise it with my number set still it is 10 (look at the numbers set above 1 means 1 , and 0 means 0)
Here are some examples, for you to understand
“xyPy” + 1 = “xyPz”
“xyPz” + 1 = “xyQ0”
now that is all you have to understand, basically you crate a number which use alpha-numeric as the symbols to represent it and you do the exact same thing what you did in base 10 (1-9 numbers ) with a different base, base 62
here is the concept implementation using java
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
/*
* This class generate alpha numeric ID incrementally starting from a
* given ID
*
* @author imal hasaranga
* @version 1.0
* @since 2014-07-13
*
* */
public class VIDocID {
// This is my number set it contains 62 symbols
private final List numberset = Arrays.asList(
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'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',
'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'
);
private String initAL; // keep starting AN
private int BASE; // base of numberset is 62 so, addition = (anynumber %
// BASE) and spare = (anynumber / 62)
public VIDocID(String initAL) {
// initializing the values
this.initAL = initAL;
this.BASE = numberset.size();
}
public synchronized String nextAN() {
char[] number = initAL.toCharArray();
int spare = 0;
int addition = 1;
/*
* Here what i'm doing is i'm looping the given string backwards and get
* char by char
*/
for (int i = number.length - 1; i >= 0; i--) {
int lastnumber = numberset.indexOf(number[i]);
/*
* abov i'm getting number associated with the last char, example
* letter "A" means 10 and in the below line i'm adding +1, also if
* there is number left in the previous calculation I'm adding it
* too
*/
int newnumb = lastnumber + addition + spare;
/*
* now i'm checking whether the new number is exceeding the base,
* example, in normal number set is 9+1 = 10
*/
if (newnumb >= BASE) {
// calculate spare and the addition
number[i] = numberset.get(newnumb % BASE);
spare = newnumb / BASE;
} else {
/*
if the addition is not exceeding the base then we can just
add them
and stop there
*/
number[i] = numberset.get(newnumb);
break;
}
/*
checkin a special situation, spare can be 1 but sometimes number
might have end in the next iteration, in this case i'm adding the
spare to the front
and stoping
*/
if ((spare > 0) && ((i - 1) < 0)) {
number = (numberset.get(spare) + new String(number)).toCharArray();
break;
}
}
return initAL = new String(number);
}
public static void main(String[] args) {
VIDocID docid = new VIDocID("00");
int counter = 0;
while (true) {
++counter;
if (counter == 4000) {
break;
}
writeline("ID: " + docid.nextAN() + " Counter :" + counter);
}
}
public static void writeline(String txt){
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("keys.txt", true)))) {
out.println(txt);
}catch (IOException e) {
e.printStackTrace();
}
}
}