Home > Software design >  How to map a 4 character long string made of 10 possible characters to a range between 1 and 10000 i
How to map a 4 character long string made of 10 possible characters to a range between 1 and 10000 i

Time:10-30

Here's what I'm trying to do:

  1. I have characters DISCOUNT23

  2. I generate codes out of these like DNT2 or CTDI

  • There is 10,000 possible codes
  1. I want 100 of these codes to be valid

  2. I want to map 10,000 possible strings to numbers between 1 and 10,000

  3. I want to make first 100 numbers to be valid

  • If string DISC is mapped to 175 it is NOT valid

  • If string DIS3 is mapped to 23 it is valid

I want this mapping to be secret but not random so I don't want to store valid codes in a database but I also don't want code DISC to be mapped to 1234 or DIS3 mapped to 1230

Basically, I want to encrypt codes made out of characters DISCOUNT23 into numbers between 1 and 10,000, so when I encrypt a code like 23DS I want to get a number like 27 and when I decrypt the number 27 I want to get the code 23DS

CodePudding user response:

My class encrypts and decrypts on a character-by-character basis. The character mappings are rotated in a modulo 10 fashion depending on the character position:

internal class Mapper
    {
        const string CodeChars = "DISCOUNT23";  //  10 characters
        const int CodeLen = 4;                  //  10^4 possible words

        public static int Encrypt(string code)
        {
            Debug.Assert(code.Length == CodeLen);

            int w = 0;

            for (int pos = 0; pos < CodeLen; pos  )
            {
                //  every char in code word gets
                //  a value according to the CodeChars
                char c = code[pos];
                int cVal = CodeChars.IndexOf(c);
                Debug.Assert(cVal >= 0);

                //  values are altered dependent on the position
                cVal = (cVal   pos   7) % 10;
                w = 10 * w   cVal;
            }

            return w;
        }

        public static string Decrypt(int val)
        {
            string s = "";

            for (int pos = 0; pos < CodeLen; pos  )
            {
                int p = (val % 10);

                int v = (p   14 - CodeLen   pos) % 10;

                s = CodeChars[v]   s;

                val /= 10;
            }

            return s;
        }

        public static void Test()
        {
            string[] words = {"DISC", "ISC3", "23DS" };

            foreach(var w in words)
            {
                var e = Encrypt(w);
                var d = Decrypt(e);
                Debug.WriteLine($"{w} ==> {e} ==> {d}");
                //  Debug.Assert(d == w);
            }

            for (int i = 1; i < 10; i  )
            {
                var d = Decrypt(i);
                var e = Encrypt(d);
                Debug.WriteLine($"{i} ==> {d} ==> {e}");
                Debug.Assert(i == e);
            }

            Debug.WriteLine("ciao!");
        }
    }

Results of the test code:

DISC ==> 7913 ==> DISC
ISC3 ==> 8029 ==> ISC3
23DS ==> 5792 ==> 23DS
1 ==> CSII ==> 1
2 ==> CSIS ==> 2
3 ==> CSIC ==> 3
4 ==> CSIO ==> 4
5 ==> CSIU ==> 5
6 ==> CSIN ==> 6
7 ==> CSIT ==> 7
8 ==> CSI2 ==> 8
9 ==> CSI3 ==> 9
  • Related