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)); }
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()); }