海明码编码的原理这里不介绍了,网上有很多,我也是看了很多,这里简单实现了一个编码4字节的海明码实现。
void encode(unsigned char data[4], unsigned char code[5]) {
unsigned int i, j, bit;
unsigned char b, c;
unsigned char p[39] = {0};
memset(code, 0, sizeof(code));
for (i = 1; i <= 32; i++) {
j = (i-1) / 8;
bit = (i-1) % 8;
b = (data[j] & (1 << bit));
switch (i) {
case 1:
c = (b << 2) % 0xff;
code[0] |= c;
break;
case 2: case 3: case 4:
c = (b << 3) % 0xff;
code[0] |= c;
break;
case 5: case 6: case 7: case 8: case 9: case 10: case 11:
c = (b << 4) % 0xff;
code[1] |= c;
break;
case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19:
c = (b << 5) % 0xff;
code[2] |= c;
break;
case 20: case 21: case 22: case 23: case 24: case 25: case 26:
c = (b << 5) % 0xff;
code[3] |= c;
break;
case 27: case 28: case 29: case 30: case 31: case 32:
c = (b << 6) % 0xff;
code[4] |= c;
break;
}
}
for (i = 1; i <= 38; i++) {
if (i != 0x01 && i != 0x02 && i != 0x04 && i != 0x08 && i != 0x10 && i != 0x20) {
bit = (i-1) % 8;
switch (i) {
case 3: case 5: case 6: case 7:
p[i] = (code[0] & (1 << bit)) >> bit;
break;
case 9: case 10: case 11: case 12: case 13: case 14: case 15:
p[i] = (code[1] & (1 << bit)) >> bit;
break;
case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24:
p[i] = (code[2] & (1 << bit)) >> bit;
break;
case 25: case 26: case 27: case 28: case 29: case 30: case 31:
p[i] = (code[3] & (1 << bit)) >> bit;
break;
case 33: case 34: case 35: case 36: case 37: case 38:
p[i] = (code[4] & (1 << bit)) >> bit;
break;
}
}
}
p[1] = p[3] ^ p[5] ^ p[7] ^ p[9] ^ p[11] ^ p[13] ^ p[15] ^ p[17] ^ p[19] ^ p[21] ^ p[23] ^ p[25] ^ p[27] ^ p[29] ^ p[31] ^ p[33] ^ p[35] ^ p[37];
p[2] = p[3] ^ p[6] ^ p[7] ^ p[10] ^ p[11] ^ p[14] ^ p[15] ^ p[18] ^ p[19] ^ p[22] ^ p[23] ^ p[26] ^ p[27] ^ p[30] ^ p[31] ^ p[34] ^ p[35] ^ p[38];
p[4] = p[5] ^ p[6] ^ p[7] ^ p[12] ^ p[13] ^ p[14] ^ p[15] ^ p[20] ^ p[21] ^ p[22] ^ p[23] ^ p[28] ^ p[29] ^ p[30] ^ p[31] ^ p[36] ^ p[37] ^ p[38];
p[8] = p[9] ^ p[10] ^ p[11] ^ p[12] ^ p[13] ^ p[14] ^ p[15] ^ p[24] ^ p[25] ^ p[26] ^ p[27] ^ p[28] ^ p[29] ^ p[30] ^ p[31];
p[16] = p[17] ^ p[18] ^ p[19] ^ p[20] ^ p[21] ^ p[22] ^ p[23] ^ p[24] ^ p[25] ^ p[26] ^ p[27] ^ p[28] ^ p[29] ^ p[30] ^ p[31];
p[32] = p[33] ^ p[34] ^ p[35] ^ p[36] ^ p[37] ^ p[38];
code[0] |= p[1];
code[0] |= (p[2] << 1);
code[0] |= (p[4] << 3);
code[0] |= (p[8] << 7);
code[1] |= (p[16] << 7);
code[3] |= (p[32] << 7);
}
void code_to_bitarray(unsigned char code[5], unsigned char p[39]) {
unsigned int i, j, bit;
for (i = 1; i <= 38; i++) {
j = i - 1;
bit = j % 8;
p[i] = (code[j / 8] & (1 << bit)) >> bit;
}
}
void bitarray_to_wng(unsigned char p[39], unsigned char wng[6]) {
wng[0] = p[1] ^ p[3] ^ p[5] ^ p[7] ^ p[9] ^ p[11] ^ p[13] ^ p[15] ^ p[17] ^ p[19] ^ p[21] ^ p[23] ^ p[25] ^ p[27] ^ p[29] ^ p[31] ^ p[33] ^ p[35] ^ p[37];
wng[1] = p[2] ^ p[3] ^ p[6] ^ p[7] ^ p[10] ^ p[11] ^ p[14] ^ p[15] ^ p[18] ^ p[19] ^ p[22] ^ p[23] ^ p[26] ^ p[27] ^ p[30] ^ p[31] ^ p[34] ^ p[35] ^ p[38];
wng[2] = p[4] ^ p[5] ^ p[6] ^ p[7] ^ p[12] ^ p[13] ^ p[14] ^ p[15] ^ p[20] ^ p[21] ^ p[22] ^ p[23] ^ p[28] ^ p[29] ^ p[30] ^ p[31] ^ p[36] ^ p[37] ^ p[38];
wng[3] = p[8] ^ p[9] ^ p[10] ^ p[11] ^ p[12] ^ p[13] ^ p[14] ^ p[15] ^ p[24] ^ p[25] ^ p[26] ^ p[27] ^ p[28] ^ p[29] ^ p[30] ^ p[31];
wng[4] = p[16] ^ p[17] ^ p[18] ^ p[19] ^ p[20] ^ p[21] ^ p[22] ^ p[23] ^ p[24] ^ p[25] ^ p[26] ^ p[27] ^ p[28] ^ p[29] ^ p[30] ^ p[31];
wng[5] = p[32] ^ p[33] ^ p[34] ^ p[35] ^ p[36] ^ p[37] ^ p[38];
}
unsigned char locate_bit(unsigned char wng[6]) {
unsigned char loc = 0;
char i = 0;
for (i = 5; i >= 0; i--) {
loc |= (wng[i] << i);
}
return loc;
}
void bitarray_to_code(unsigned char p[39], unsigned char code[5]) {
unsigned int i, j;
unsigned char bit;
memset(code, 0, sizeof(code));
for(i = 1; i <= 38; i++) {
j = i - 1;
bit = j % 8;
code[j / 8] |= (p[i] << bit);
}
}
void bitarray_to_data(unsigned char p[39], unsigned char data[4]) {
memset(data, 0, sizeof(data));
unsigned char d[32];
unsigned char bit = 0;
unsigned int i, j;
j = 0;
for (i = 1; i <= 38; i++) {
if (i != 1 && i != 2 && i != 4 && i != 8 && i != 16 && i != 32) {
d[j++] = p[i];
}
}
for (i = 0; i < 32; i++) {
bit = i % 8;
data[i / 8] |= (d[i] << bit);
}
}
bool decode(unsigned char code[5], unsigned char data[4]) {
unsigned char bit;
unsigned char p[39] = {0};
unsigned char wng[6] = {0};
unsigned char loc = 0;
code_to_bitarray(code, p);
bitarray_to_wng(p, wng);
loc = locate_bit(wng);
if (0 == loc) {
bitarray_to_data(p, data);
return true;
} else {
p[loc] = 1 - p[loc];
bitarray_to_code(p, code);
bitarray_to_data(p, data);
return false;
}
}
void filename_to_code(char filename[32], char filename_code[40]) {
int i = 0;
for(i = 0; i < 8; i++) {
encode((unsigned char*)(filename + i * 4), (unsigned char*)(filename_code + i * 5));
}
}
void code_to_filename(char filename_code[40], char filename[32]) {
int i = 0;
for (i = 0; i < 8; i++) {
decode((unsigned char*)(filename_code + i * 5), (unsigned char*)(filename + i * 4));
}
}
我用一个main程序测试
int main(int argc, char* argv[]) {
char filename[32] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ01234";
char filename_code[40];
char filename_dst[32];
filename_to_code(filename, filename_code);
code_to_filename(filename_code, filename_dst);
cout << filename <<endl;
cout << filename_dst << endl;
return 0;
}
输出结果经过编码解码之后的内容一致。
ABCDEFGHIJKLMNOPQRSTUVWXYZ01234
ABCDEFGHIJKLMNOPQRSTUVWXYZ01234