📄 test_hamming.cpp
字号:
// test_hamming.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#define DATA_BLOCK_LEN 256
#define ECC_BUFF_LEN 6 // 3 bytes per 256 bytes of data
#define UNCORRECTABLE_ERROR 1
#define CORRECTABLE_ERROR 11
//------------------------------ Helper Functions ------------------------------
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: CountNumberOfOnes()
Description: Counts the number of bits that are "1" in a byte.
Returns: Number of bits that are "1".
-------------------------------------------------------------------------------*/
UCHAR CountNumberOfOnes(UCHAR num)
{
UCHAR count = 0;
while(num)
{
num=num&(num-1);
count++;
}
return count;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: ECC_ComputeECC()
Description: Computes the error correcting code for the specified data.
Notes: The following implementation uses a Hammming Code to compute
3 bytes of ECC information for every 256 bytes of data. It is
the caller's responsibility to insure the input buffers meet this
constraint...
Returns: Boolean indicating success.
-------------------------------------------------------------------------------*/
BOOL ECC_ComputeECC_old(LPBYTE pData, DWORD dwDataBuffLen, LPBYTE pECC, DWORD dwECCBuffLen)
{
static UINT i, j, k;
static UCHAR evenParity[16] = {0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0}; // Look-up table (LUT)
static UCHAR dataXOR = 0;
static UCHAR bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7;
// Column parity terms. NOTE: p subscript denotes "prime" (i.e. P1p = P1')
static UCHAR P1, P2, P4, P1p, P2p, P4p;
// Row parity terms. NOTE: p subscript denotes "prime" (i.e. P8p = P8')
UCHAR P8, P8p, P16, P16p, P32, P32p, P64, P64p, P128, P128p,
P256, P256p, P512, P512p, P1024, P1024p;
//----- 1. Check to make sure the input buffers are legitimate... -----
if((pData == NULL) || (pECC == NULL) || (dwDataBuffLen < DATA_BLOCK_LEN) || (dwECCBuffLen < ECC_BUFF_LEN) )
{
return FALSE;
}
//----- 2. Segregrate the data buffer into 256 byte blocks and compute ECC info for each block -----
for(j=0,k=0; j<dwDataBuffLen; j+= DATA_BLOCK_LEN)
{
//----- 3. Initialize the ROW parity terms -----
dataXOR = 0;
P8=0; P8p=0; P16=0; P16p=0; P32=0; P32p=0; P64=0; P64p=0;
P128=0; P128p=0; P256=0; P256p=0; P512=0; P512p=0; P1024=0; P1024p=0;
//----- 4. Compute the ROW parity terms P8, P8p, P16, ... P1024p -----
// NOTE: For speedup purposes, the otherwise 9 separate loops are unrolled into 3 large loops...
for(i=j; i<j+DATA_BLOCK_LEN; i+=32)
{
P8p ^= pData[i] ^ pData[i+2] ^ pData[i+4] ^ pData[i+6] ^ pData[i+8] ^ pData[i+10] ^ pData[i+12] ^ pData[i+14]
^ pData[i+16] ^ pData[i+18] ^ pData[i+20] ^ pData[i+22] ^ pData[i+24] ^ pData[i+26] ^ pData[i+28] ^ pData[i+30];
P8 ^= pData[i+1] ^ pData[i+3] ^ pData[i+5] ^ pData[i+7] ^ pData[i+9] ^ pData[i+11] ^ pData[i+13] ^ pData[i+15]
^ pData[i+17] ^ pData[i+19] ^ pData[i+21] ^ pData[i+23] ^ pData[i+25] ^ pData[i+27] ^ pData[i+29] ^ pData[i+31];
P16p ^= pData[i] ^ pData[i+1] ^ pData[i+4] ^ pData[i+5] ^ pData[i+8] ^ pData[i+9] ^ pData[i+12] ^ pData[i+13]
^ pData[i+16] ^ pData[i+17] ^ pData[i+20] ^ pData[i+21] ^ pData[i+24] ^ pData[i+25] ^ pData[i+28] ^ pData[i+29];
P16 ^= pData[i+2] ^ pData[i+3] ^ pData[i+6] ^ pData[i+7] ^ pData[i+10] ^ pData[i+11] ^ pData[i+14] ^ pData[i+15]
^ pData[i+18] ^ pData[i+19] ^ pData[i+22] ^ pData[i+23] ^ pData[i+26] ^ pData[i+27] ^ pData[i+30] ^ pData[i+31];
P32p ^= pData[i] ^ pData[i+1] ^ pData[i+2] ^ pData[i+3] ^ pData[i+8] ^ pData[i+9] ^ pData[i+10] ^ pData[i+11]
^ pData[i+16] ^ pData[i+17] ^ pData[i+18] ^ pData[i+19] ^ pData[i+24] ^ pData[i+25] ^ pData[i+26] ^ pData[i+27];
P32 ^= pData[i+4] ^ pData[i+5] ^ pData[i+6] ^ pData[i+7] ^ pData[i+12] ^ pData[i+13] ^ pData[i+14] ^ pData[i+15]
^ pData[i+20] ^ pData[i+21] ^ pData[i+22] ^ pData[i+23] ^ pData[i+28] ^ pData[i+29] ^ pData[i+30] ^ pData[i+31];
P64p ^= pData[i] ^ pData[i+1] ^ pData[i+2] ^ pData[i+3] ^ pData[i+4] ^ pData[i+5] ^ pData[i+6] ^ pData[i+7]
^ pData[i+16] ^ pData[i+17] ^ pData[i+18] ^ pData[i+19] ^ pData[i+20] ^ pData[i+21] ^ pData[i+22] ^ pData[i+23];
P64 ^= pData[i+8] ^ pData[i+9] ^ pData[i+10] ^ pData[i+11] ^ pData[i+12] ^ pData[i+13] ^ pData[i+14] ^ pData[i+15]
^ pData[i+24] ^ pData[i+25] ^ pData[i+26] ^ pData[i+27] ^ pData[i+28] ^ pData[i+29] ^ pData[i+30] ^ pData[i+31];
P128p ^= pData[i] ^ pData[i+1] ^ pData[i+2] ^ pData[i+3] ^ pData[i+4] ^ pData[i+5] ^ pData[i+6] ^ pData[i+7]
^ pData[i+8] ^ pData[i+9] ^ pData[i+10] ^ pData[i+11] ^ pData[i+12] ^ pData[i+13] ^ pData[i+14] ^ pData[i+15];
P128 ^= pData[i+16] ^ pData[i+17] ^ pData[i+18] ^ pData[i+19] ^ pData[i+20] ^ pData[i+21] ^ pData[i+22] ^ pData[i+23]
^ pData[i+24] ^ pData[i+25] ^ pData[i+26] ^ pData[i+27] ^ pData[i+28] ^ pData[i+29] ^ pData[i+30] ^ pData[i+31];
}
P8p = evenParity[((P8p & 0xF0) >> 4)] ^ evenParity[(P8p & 0x0F)];
P8 = evenParity[((P8 & 0xF0) >> 4)] ^ evenParity[(P8 & 0x0F)];
P16p = evenParity[((P16p & 0xF0) >> 4)] ^ evenParity[(P16p & 0x0F)];
P16 = evenParity[((P16 & 0xF0) >> 4)] ^ evenParity[(P16 & 0x0F)];
P32p = evenParity[((P32p & 0xF0) >> 4)] ^ evenParity[(P32p & 0x0F)];
P32 = evenParity[((P32 & 0xF0) >> 4)] ^ evenParity[(P32 & 0x0F)];
P64p = evenParity[((P64p & 0xF0) >> 4)] ^ evenParity[(P64p & 0x0F)];
P64 = evenParity[((P64 & 0xF0) >> 4)] ^ evenParity[(P64 & 0x0F)];
P128p = evenParity[((P128p & 0xF0) >> 4)] ^ evenParity[(P128p & 0x0F)];
P128 = evenParity[((P128 & 0xF0) >> 4)] ^ evenParity[(P128 & 0x0F)];
for(i=j; i<j+DATA_BLOCK_LEN; i+=128)
{
P256p ^= pData[i] ^ pData[i+1] ^ pData[i+2] ^ pData[i+3] ^ pData[i+4] ^ pData[i+5] ^ pData[i+6] ^ pData[i+7]
^ pData[i+8] ^ pData[i+9] ^ pData[i+10] ^ pData[i+11] ^ pData[i+12] ^ pData[i+13] ^ pData[i+14] ^ pData[i+15]
^ pData[i+16] ^ pData[i+17] ^ pData[i+18] ^ pData[i+19] ^ pData[i+20] ^ pData[i+21] ^ pData[i+22] ^ pData[i+23]
^ pData[i+24] ^ pData[i+25] ^ pData[i+26] ^ pData[i+27] ^ pData[i+28] ^ pData[i+29] ^ pData[i+30] ^ pData[i+31]
^ pData[i+64] ^ pData[i+65] ^ pData[i+66] ^ pData[i+67] ^ pData[i+68] ^ pData[i+69] ^ pData[i+70] ^ pData[i+71]
^ pData[i+72] ^ pData[i+73] ^ pData[i+74] ^ pData[i+75] ^ pData[i+76] ^ pData[i+77] ^ pData[i+78] ^ pData[i+79]
^ pData[i+80] ^ pData[i+81] ^ pData[i+82] ^ pData[i+83] ^ pData[i+84] ^ pData[i+85] ^ pData[i+86] ^ pData[i+87]
^ pData[i+88] ^ pData[i+89] ^ pData[i+90] ^ pData[i+91] ^ pData[i+92] ^ pData[i+93] ^ pData[i+94] ^ pData[i+95];
P256 ^= pData[i+32] ^ pData[i+33] ^ pData[i+34] ^ pData[i+35] ^ pData[i+36] ^ pData[i+37] ^ pData[i+38] ^ pData[i+39]
^ pData[i+40] ^ pData[i+41] ^ pData[i+42] ^ pData[i+43] ^ pData[i+44] ^ pData[i+45] ^ pData[i+46] ^ pData[i+47]
^ pData[i+48] ^ pData[i+49] ^ pData[i+50] ^ pData[i+51] ^ pData[i+52] ^ pData[i+53] ^ pData[i+54] ^ pData[i+55]
^ pData[i+56] ^ pData[i+57] ^ pData[i+58] ^ pData[i+59] ^ pData[i+60] ^ pData[i+61] ^ pData[i+62] ^ pData[i+63]
^ pData[i+96] ^ pData[i+97] ^ pData[i+98] ^ pData[i+99] ^ pData[i+100] ^ pData[i+101] ^ pData[i+102] ^ pData[i+103]
^ pData[i+104] ^ pData[i+105] ^ pData[i+106] ^ pData[i+107] ^ pData[i+108] ^ pData[i+109] ^ pData[i+110] ^ pData[i+111]
^ pData[i+112] ^ pData[i+113] ^ pData[i+114] ^ pData[i+115] ^ pData[i+116] ^ pData[i+117] ^ pData[i+118] ^ pData[i+119]
^ pData[i+120] ^ pData[i+121] ^ pData[i+122] ^ pData[i+123] ^ pData[i+124] ^ pData[i+125] ^ pData[i+126] ^ pData[i+127];
P512p ^= pData[i] ^ pData[i+1] ^ pData[i+2] ^ pData[i+3] ^ pData[i+4] ^ pData[i+5] ^ pData[i+6] ^ pData[i+7]
^ pData[i+8] ^ pData[i+9] ^ pData[i+10] ^ pData[i+11] ^ pData[i+12] ^ pData[i+13] ^ pData[i+14] ^ pData[i+15]
^ pData[i+16] ^ pData[i+17] ^ pData[i+18] ^ pData[i+19] ^ pData[i+20] ^ pData[i+21] ^ pData[i+22] ^ pData[i+23]
^ pData[i+24] ^ pData[i+25] ^ pData[i+26] ^ pData[i+27] ^ pData[i+28] ^ pData[i+29] ^ pData[i+30] ^ pData[i+31]
^ pData[i+32] ^ pData[i+33] ^ pData[i+34] ^ pData[i+35] ^ pData[i+36] ^ pData[i+37] ^ pData[i+38] ^ pData[i+39]
^ pData[i+40] ^ pData[i+41] ^ pData[i+42] ^ pData[i+43] ^ pData[i+44] ^ pData[i+45] ^ pData[i+46] ^ pData[i+47]
^ pData[i+48] ^ pData[i+49] ^ pData[i+50] ^ pData[i+51] ^ pData[i+52] ^ pData[i+53] ^ pData[i+54] ^ pData[i+55]
^ pData[i+56] ^ pData[i+57] ^ pData[i+58] ^ pData[i+59] ^ pData[i+60] ^ pData[i+61] ^ pData[i+62] ^ pData[i+63];
P512 ^= pData[i+64] ^ pData[i+65] ^ pData[i+66] ^ pData[i+67] ^ pData[i+68] ^ pData[i+69] ^ pData[i+70] ^ pData[i+71]
^ pData[i+72] ^ pData[i+73] ^ pData[i+74] ^ pData[i+75] ^ pData[i+76] ^ pData[i+77] ^ pData[i+78] ^ pData[i+79]
^ pData[i+80] ^ pData[i+81] ^ pData[i+82] ^ pData[i+83] ^ pData[i+84] ^ pData[i+85] ^ pData[i+86] ^ pData[i+87]
^ pData[i+88] ^ pData[i+89] ^ pData[i+90] ^ pData[i+91] ^ pData[i+92] ^ pData[i+93] ^ pData[i+94] ^ pData[i+95]
^ pData[i+96] ^ pData[i+97] ^ pData[i+98] ^ pData[i+99] ^ pData[i+100] ^ pData[i+101] ^ pData[i+102] ^ pData[i+103]
^ pData[i+104] ^ pData[i+105] ^ pData[i+106] ^ pData[i+107] ^ pData[i+108] ^ pData[i+109] ^ pData[i+110] ^ pData[i+111]
^ pData[i+112] ^ pData[i+113] ^ pData[i+114] ^ pData[i+115] ^ pData[i+116] ^ pData[i+117] ^ pData[i+118] ^ pData[i+119]
^ pData[i+120] ^ pData[i+121] ^ pData[i+122] ^ pData[i+123] ^ pData[i+124] ^ pData[i+125] ^ pData[i+126] ^ pData[i+127];
}
P256p = evenParity[((P256p & 0xF0) >> 4)] ^ evenParity[(P256p & 0x0F)];
P256 = evenParity[((P256 & 0xF0) >> 4)] ^ evenParity[(P256 & 0x0F)];
P512p = evenParity[((P512p & 0xF0) >> 4)] ^ evenParity[(P512p & 0x0F)];
P512 = evenParity[((P512 & 0xF0) >> 4)] ^ evenParity[(P512 & 0x0F)];
for(i=j; i<j+(DATA_BLOCK_LEN>>1); i++)
{
P1024p ^= pData[i];
P1024 ^= pData[i+128];
}
// XOR all of the data bytes (used to compute COLUMN parity terms)
dataXOR = P1024p ^ P1024;
P1024p = evenParity[((P1024p & 0xF0) >> 4)] ^ evenParity[(P1024p & 0x0F)];
P1024 = evenParity[((P1024 & 0xF0) >> 4)] ^ evenParity[(P1024 & 0x0F)];
//----- 5. Determine the value of each bit in XORed value -----
// NOTE: The bit values are needed in order to compute
// the COLUMN parity values
bit0 = ((dataXOR & 0x01) ? 1 : 0);
bit1 = ((dataXOR & 0x02) ? 1 : 0);
bit2 = ((dataXOR & 0x04) ? 1 : 0);
bit3 = ((dataXOR & 0x08) ? 1 : 0);
bit4 = ((dataXOR & 0x10) ? 1 : 0);
bit5 = ((dataXOR & 0x20) ? 1 : 0);
bit6 = ((dataXOR & 0x40) ? 1 : 0);
bit7 = ((dataXOR & 0x80) ? 1 : 0);
//----- 6. Compute the COLUMN parity terms P1, P2p, P2, ... P4p -----
P1 = bit7 ^ bit5 ^ bit3 ^ bit1; P1p = bit6 ^ bit4 ^ bit2 ^ bit0;
P2 = bit7 ^ bit6 ^ bit3 ^ bit2; P2p = bit5 ^ bit4 ^ bit1 ^ bit0;
P4 = bit7 ^ bit6 ^ bit5 ^ bit4; P4p = bit3 ^ bit2 ^ bit1 ^ bit0;
//----- 7. Now, using the individual terms, construct the 22-bit Hamming Code -----
// NOTE: The Hamming Code layout is as follows:
//
// Byte0: { P1024 | P1024p | P512 | P512p | P256 | P256p | P128 | P128p }
// Byte1: { P64 | P64p | P32 | P32p | P16 | P16p | P8 | P8p }
// Byte2: { P4 | P4p | P2 | P2p | P1 | P1p | 1 | 1 }
//
P1p <<= 2; P1 <<= 3;
P2p <<= 4; P2 <<= 5;
P4p <<= 6; P4 <<= 7;
P8p <<= 0; P8 <<= 1;
P16p <<= 2; P16 <<= 3;
P32p <<= 4; P32 <<= 5;
P64p <<= 6; P64 <<= 7;
P128p <<= 0; P128 <<= 1;
P256p <<= 2; P256 <<= 3;
P512p <<= 4; P512 <<= 5;
P1024p <<= 6; P1024 <<= 7;
pECC[k++] = (P1024 | P1024p | P512 | P512p | P256 | P256p | P128 | P128p);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -