/// <summary> /// Кодирует данные /// </summary> /// <param name="data">Данные для кодирования</param> /// <param name="t">Количество исправляемых ошибок</param> /// <returns></returns> public static byte[] Encode(byte[] data, int t = 3) { if (t < 1 || t > 5) { throw new ArgumentOutOfRangeException(); } RSCoder coder = new RSCoder(t); byte[] dataWithLen = new byte[data.Length + sizeof(int)]; int size = data.Length; for (int i = 0; i < sizeof(int); ++i) { dataWithLen[i] = (byte)(size % 256); size /= 256; } for (int i = 0; i < data.Length; ++i) { dataWithLen[i + sizeof(int)] = data[i]; } byte[] input = ToHex(dataWithLen, mm); int blocksCnt = (int)Math.Ceiling(input.Length / (double)coder.kk); byte[] output = new byte[blocksCnt * coder.nn]; for (int i = 0; i < blocksCnt; ++i) { for (int j = 0; j < coder.kk; ++j) { coder.data[j] = (input.Length > j + i * coder.kk) ? input[j + i * coder.kk] : 0; } coder.Encode_rs(); for (int j = 0; j < coder.nn - coder.kk; ++j) { output[j + i * coder.nn] = (byte)coder.bb[j]; } for (int j = 0; j < coder.kk; ++j) { output[j + i * coder.nn + coder.nn - coder.kk] = (byte)coder.data[j]; } } return(ToByte(output, mm)); }
public static byte[] decode(byte[] data, int t = 3) { if (t < 1 || t > 5) { throw new ArgumentOutOfRangeException(); } RSCoder coder = new RSCoder(t); byte[] input = toOct(data, coder.mm); int blocksCnt = (int)Math.Ceiling(input.Length / (double)coder.nn); byte[] output = new byte[blocksCnt * coder.kk]; for (int i = 0; i < blocksCnt; ++i) { if (debug) { Console.WriteLine("INPUT[{0:D}]", i); } for (int j = 0; j < coder.nn; ++j) { coder.recd[j] = (input.Length > j + i * coder.nn) ? coder.index_of[input[j + i * coder.nn]] : 0; if (debug) { Console.Write("{0:D} ", coder.recd[j]); } } if (debug) { Console.WriteLine(); } coder.decode_rs(); if (debug) { Console.WriteLine("OUTPUT[{0:D}]", i); } for (int j = 0; j < coder.kk; ++j) { output[j + i * coder.kk] = (byte)(coder.recd[j + coder.nn - coder.kk]); if (debug) { Console.Write("{0:D} ", output[j + i * coder.kk]); } } if (debug) { Console.WriteLine(); } } output = toByte(output, coder.mm); int size = 0; for (int i = sizeof(int) - 1; i >= 0; --i) { size = size * 256 + output [i]; } if ((size <= 0) || (size > output.Length + sizeof(int))) { throw new Exception(String.Format("Incorrect size = {0:D}!", size)); } byte[] decoded = new byte[size]; for (int i = 0; i < decoded.Length; ++i) { decoded [i] = output [i + sizeof(int)]; } return(decoded); }
public static byte[] encode(byte[] data, int t = 3) { if (t < 1 || t > 5) { throw new ArgumentOutOfRangeException(); } RSCoder coder = new RSCoder(t); byte[] dataWithLen = new byte[data.Length + sizeof(int)]; int size = data.Length; for (int i = 0; i < sizeof(int); ++i) { dataWithLen [i] = (byte)(size % 256); size /= 256; } for (int i = 0; i < data.Length; ++i) { dataWithLen [i + sizeof(int)] = data [i]; } byte[] input = toOct(dataWithLen, coder.mm); int blocksCnt = (int)Math.Ceiling(input.Length / (double)coder.kk); byte[] output = new byte[blocksCnt * coder.nn]; for (int i = 0; i < blocksCnt; ++i) { if (debug) { Console.WriteLine("INPUT[{0:D}]", i); } for (int j = 0; j < coder.kk; ++j) { coder.data[j] = (input.Length > j + i * coder.kk) ? input[j + i * coder.kk] : 0; if (debug) { Console.Write("{0:D} ", coder.data[j]); } } if (debug) { Console.WriteLine(); } coder.encode_rs(); if (debug) { Console.WriteLine("OUTPUT[{0:D}]", i); } for (int j = 0; j < coder.nn - coder.kk; ++j) { output[j + i * coder.nn] = (byte)coder.bb[j]; if (debug) { Console.Write("{0:D} ", output[j + i * coder.nn]); } } for (int j = 0; j < coder.kk; ++j) { output[j + i * coder.nn + coder.nn - coder.kk] = (byte)coder.data[j]; if (debug) { Console.Write("{0:D} ", output[j + i * coder.nn + coder.nn - coder.kk]); } } if (debug) { Console.WriteLine(); } } return(toByte(output, coder.mm)); }
/// <summary> /// Декодирует данные /// </summary> /// <param name="data">Данные для декодирования</param> /// <param name="t">Количество исправляемых ошибок</param> /// <returns></returns> public static byte[] Decode(byte[] data, int t = 3) { bool isErrors = false; if (t < 1 || t > 5) { throw new ArgumentOutOfRangeException(); } RSCoder coder = new RSCoder(t); byte[] input = ToHex(data, mm); int blocksCnt = (int)Math.Ceiling(input.Length / (double)coder.nn); byte[] output = new byte[blocksCnt * coder.kk]; for (int i = 0; i < blocksCnt; ++i) { for (int j = 0; j < coder.nn; ++j) { coder.recd[j] = (input.Length > j + i * coder.nn) ? coder.index_of[input[j + i * coder.nn]] : 0; } coder.Decode_rs(); if (!coder.canDecode) { isErrors = true; } for (int j = 0; j < coder.kk; ++j) { output[j + i * coder.kk] = (byte)(coder.recd[j + coder.nn - coder.kk]); } } output = ToByte(output, mm); int size = 0; for (int i = sizeof(int) - 1; i >= 0; --i) { size = size * 256 + output[i]; } if ((size <= 0) || (size > output.Length + sizeof(int))) { throw new Exception(String.Format("Incorrect size = {0:D}!", size)); } byte[] decoded = new byte[size]; for (int i = 0; i < decoded.Length; ++i) { decoded[i] = output[i + sizeof(int)]; } if (isErrors) { data[0] = 255; } else { data[0] = 0; } return(decoded); }