7
\$\begingroup\$

I have to generate the unique key having a length of 8, which should be comprised of some set of characters:

{B,C,D,F,G,H,J,K,L,M,N,P,Q,R,S,T,V,W,X,Y,Z,2,3,4,5,6,7,8,9}

Now I have written a program that will generate it, but I am not sure it will generate the unique key. Could you please review it?.

static string[]  unicode = {"66","67","68","70","71","72","74","75","76","77","78","80","81","82","83","84","86","87","88","89","90","50","51","52","53","54","55","56","57"};

These are the ASCII representation of above character:

long k=5050505050505050; // this initially starts from 5050505050505050

List<string> lst=new List<string>();
void Main(){ 
    while(lst.Count()<1000000 && k!=9090909090909090)
    {

        var NoSet=Split(k.ToString(),2);

        if(NoSet.Count()==8){

            var no=string.Join("",NoSet.Select(x=>(char)(Convert.ToInt32(x))));
            lst.Add(no);

        }

        k++;
    }
}

Finally, store the last value of K variable to generate the next 1000000 unique key:

static IEnumerable<string> Split(string str, int chunkSize){
return Enumerable.Range(0, str.Length / chunkSize)
    .Select(i => str.Substring(i * chunkSize, chunkSize)).Where(x=>unicode.Contains(x)).Select(x=>x);}

Output from the list:

22222222

22222223

22222224

22222225

22222226

22222227

22222228

22222229

2222222B

2222222C

2222222D

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Why an 8 character set? This problem has been solved in the way of GUIDs already. (Granted, they're larger and not 100% guaranteed of being unique, but I promise you it's a better solution than rolling your own.) \$\endgroup\$
    – RubberDuck
    Jun 14, 2014 at 20:51
  • 2
    \$\begingroup\$ Thanks @ckuhn203 but we have a business requirement cause key should be human readable and memorable you can assume it like a batch no of product. \$\endgroup\$
    – ni3.net
    Jun 15, 2014 at 4:52

1 Answer 1

6
\$\begingroup\$

It looks from the data as if you do not need the numbers to be random, only unique.
A solution is to take the numbers from 1 to 1,000,000 but output them in base 29 using the allowed characters.

private static readonly char[] Values = {
        'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z', '2',
        '3', '4', '5', '6', '7', '8', '9'
    };

private static readonly int ValueCount = Values.Length;

private IEnumerable<string> GenerateValues(int count) {
    for (var c = 0; c < count; c++) {
        yield return FormatNumber(c);
    }
}

private static string FormatNumber(int value) {

    var digits = new[] { Values[0], Values[0], Values[0], Values[0], Values[0], Values[0], Values[0], Values[0] };
    var slotCount = digits.Length;

    var current = value;
    var count = 0;
    while (current > 0) {
        int rem;
        current = Math.DivRem(current, ValueCount, out rem);
        digits[slotCount - ++count] = Values[rem];
    }

    return new string(digits);
}

This will generate:

BBBBBBBB  (0)
BBBBBBBC  (1)
BBBBBBBD  (2)
...
BBBCQBC3  (1,000,000)

you can modify it to start at any point and to generate different amount of Ids (up to \$29^8-1\$)

\$\endgroup\$
2

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.