Beispiel #1
0
        public static ulong Decode(String cypher_string)
        {
            int[] codeword = new int[ReedSolomon.initial_codeword.Length];
            Array.Copy(ReedSolomon.initial_codeword, 0, codeword, 0, ReedSolomon.initial_codeword.Length);

            int codeword_length = 0;

            for (int i = 0; i < cypher_string.Length; i++)
            {
                int position_in_alphabet = ReedSolomon.alphabet.IndexOf(cypher_string[i]);

                if (position_in_alphabet <= -1 || position_in_alphabet > ReedSolomon.alphabet.Length)
                {
                    continue;
                }

                if (codeword_length > 16)
                {
                    throw new CodewordTooLongException();
                }

                int codework_index = ReedSolomon.codeword_map[codeword_length];
                codeword[codework_index] = position_in_alphabet;
                codeword_length         += 1;
            }

            if (codeword_length == 17 && !ReedSolomon.is_codeword_valid(codeword) || codeword_length != 17)
            {
                throw new CodewordInvalidException();
            }

            int length = ReedSolomon.base_32_length;

            int[] cypher_string_32 = new int[length];
            for (int i = 0; i < length; i++)
            {
                cypher_string_32[i] = codeword[length - i - 1];
            }

            StringBuilder plain_string_builder = new StringBuilder();

            do
            { // base 32 to base 10 conversion
                int new_length = 0;
                int digit_10   = 0;

                for (int i = 0; i < length; i++)
                {
                    digit_10 = digit_10 * 32 + cypher_string_32[i];

                    if (digit_10 >= 10)
                    {
                        cypher_string_32[new_length] = digit_10 / 10;
                        digit_10   %= 10;
                        new_length += 1;
                    }
                    else if (new_length > 0)
                    {
                        cypher_string_32[new_length] = 0;
                        new_length += 1;
                    }
                }
                length = new_length;
                plain_string_builder.Append((char)(digit_10 + (int)'0'));
            } while (length > 0);

            var str = new String(plain_string_builder.ToString().ToCharArray().Reverse().ToArray());

            return(Convert.ToUInt64(str));
        }
Beispiel #2
0
        public static String Encode(ulong plain)
        {
            String plain_string = Convert.ToString(plain);
            int    length       = plain_string.Length;

            int[] plain_string_10 = new int[ReedSolomon.base_10_length];
            for (int i = 0; i < length; i++)
            {
                plain_string_10[i] = (int)plain_string[i] - (int)'0';
            }

            int codeword_length = 0;

            int[] codeword = new int[ReedSolomon.initial_codeword.Length];

            do
            {  // base 10 to base 32 conversion
                int new_length = 0;
                int digit_32   = 0;
                for (int i = 0; i < length; i++)
                {
                    digit_32 = digit_32 * 10 + plain_string_10[i];
                    if (digit_32 >= 32)
                    {
                        plain_string_10[new_length] = digit_32 >> 5;
                        digit_32   &= 31;
                        new_length += 1;
                    }
                    else if (new_length > 0)
                    {
                        plain_string_10[new_length] = 0;
                        new_length += 1;
                    }
                }
                length = new_length;
                codeword[codeword_length] = digit_32;
                codeword_length          += 1;
            } while (length > 0);

            int[] p = { 0, 0, 0, 0 };
            for (int i = ReedSolomon.base_32_length - 1; i >= 0; i--)
            {
                int fb = codeword[i] ^ p[3];
                p[3] = p[2] ^ ReedSolomon.gmult(30, fb);
                p[2] = p[1] ^ ReedSolomon.gmult(6, fb);
                p[1] = p[0] ^ ReedSolomon.gmult(9, fb);
                p[0] = ReedSolomon.gmult(17, fb);
            }

            Array.Copy(p, 0, codeword, ReedSolomon.base_32_length, ReedSolomon.initial_codeword.Length - ReedSolomon.base_32_length);

            StringBuilder cypher_string_builder = new StringBuilder();

            for (int i = 0; i < 17; i++)
            {
                int codework_index = ReedSolomon.codeword_map[i];
                int alphabet_index = codeword[codework_index];
                cypher_string_builder.Append(ReedSolomon.alphabet[alphabet_index]);

                if ((i & 3) == 3 && i < 13)
                {
                    cypher_string_builder.Append('-');
                }
            }
            return(cypher_string_builder.ToString());
        }