// This code is Reed Mahler's decoder for RM (30,14) // The code is not universal, optimized for tetra // Recovers 3 bits out of 30 transmitted. public unsafe void Test() { var rnd = new Random(); var inTestBuffer = UnsafeBuffer.Create(32, sizeof(byte)); var inTestBufferPtr = (byte *)inTestBuffer; var outTestBuffer = UnsafeBuffer.Create(14, sizeof(byte)); var outTestBufferPtr = (byte *)outTestBuffer; var result = (uint)0; var checkBit = (uint)0; var error = 0; // All possible options, 16K x 30 bits for (int j = 1; j < 16384; j++) { result = 0; for (int column = 0; column < 30; column++) { checkBit = 0; for (int row = 0; row < 14; row++) { checkBit ^= (uint)((j >> (13 - row)) & 1) & gMatrix[row, column]; } result <<= 1; result |= (uint)checkBit; } var data = result; for (int n = 0; n < 3; n++) { var bitNum = rnd.Next(0, 29); data ^= (1u << bitNum); } TetraUtils.UIntToBits(data, inTestBufferPtr, 2); Process(inTestBufferPtr, outTestBufferPtr); data = TetraUtils.BitsToUInt32(outTestBufferPtr, 0, 14); if ((result >> 16) != data) { error++; } } }
public unsafe bool Process(byte *inBuffer, byte *outBuffer) { uint alphaValue = 0; int counter = 0; //Принятое кодовое слово var vector = TetraUtils.BitsToUInt32(inBuffer, 0, n); int syndromeI = 0; for (int i = 0; i < nk; i++) { alphaValue = vector & _hMatrixUintPtr[i]; counter = _onesCounterPtr[alphaValue & 0xff] + _onesCounterPtr[(alphaValue >> 8) & 0xff] + _onesCounterPtr[(alphaValue >> 16) & 0xff] + _onesCounterPtr[(alphaValue >> 24) & 0xff]; syndromeI <<= 1; syndromeI |= (counter & 1); } var noErrors = (syndromeI == 0); if (!noErrors) { var bitMask = _syndromesDecoderPtr[syndromeI]; vector ^= bitMask; noErrors = bitMask != 0; } for (int i = 0; i < k; i++) { outBuffer[i] = (byte)((vector & msb) == 0 ? 0 : 1); vector <<= 1; } return(noErrors); }