#include <stdio.h>
#define XOK 0
#define XERROR -1
typedef int xt_s32;
typedef unsigned int xt_u32;
typedef char * xt_string;
typedef unsigned char xt_u8;
xt_s32 num2binstr(xt_s32 a, xt_string p, xt_u8 bitNeed)
{
xt_s32 i = 0;
if (!p || bitNeed > (sizeof(a) << 3))
return XERROR;
if (a) {
while (!((a << i) & (1 << ((sizeof(a) << 3) - 1))))i++;
i = (sizeof(a) << 3) - i;
}
if (bitNeed > i)
i = bitNeed;
while (i--)
*(p++) = (a & (1 << i)) ? '1':'0';
*p = 0;
return XOK;
}
xt_s32 binstr2num(xt_string p)
{
int a = 0;
if (!p)
return -1;
while(*p) {
if (a)
a <<= 1;
if (*p++ == '1')
a |= 1;
}
return a;
}
xt_s32 hammingCodeEncode(xt_u32 data, xt_u32 bit_len, xt_string out)
{
xt_s32 i = 0;
xt_s32 j = 0;
xt_s32 k = 0;
xt_u8 xor[32] = {0};
xt_s32 code_len = 0;
xt_s32 check_len = 0;
xt_u8 code[32] = {0};
xt_u8 origin[32] = {0};
for (i = 1;; i++) {
if ((1 << i) - 1 >= bit_len + i) {
code_len = i + bit_len;
check_len = i;
break;
}
}
num2binstr(data, origin, bit_len);
for (i = 1; i <= code_len; i++) {
if(i & (i - 1)) {
code[i - 1] = origin[j++] - '0';
if (code[i - 1]) {
xt_u8 pos[32] = {0};
num2binstr(i, pos, check_len);
for (k = 0; k < check_len; k++) {
xor[k] ^= (pos[k] - '0');
}
}
}
}
for (i = 0; i < check_len; i++) {
code[(1 << i) - 1] = xor[check_len - i - 1];
}
for (i = 0; i < code_len; i++)
out[i] = code[i] + '0';
return XOK;
}
xt_s32 hammingCodeDecode(xt_string data, xt_u32 bit_len, xt_string src, xt_u32 *pout)
{
xt_s32 i = 0;
xt_s32 j = 0;
xt_s32 k = 0;
xt_s32 xor = 0;
xt_s32 error = 0;
xt_u8 out[32] = {0};
xt_s32 code_len = 0;
xt_s32 check_len = 0;
for (i = 1;; i++) {
if ((1 << i) - 1 >= bit_len + i) {
code_len = i + bit_len;
check_len = i;
break;
}
}
//check error
for (i = 0; i < check_len; i++) {
for (j = (1 << i); j <= code_len;) {
for (k = j; k <= code_len && k < j + (1 << i); k++) {
xor ^= data[k - 1] - '0';
}
j += 1 << (i + 1);
}
error |= (xor & 0x01) << i;
xor = 0;
}
for (i = 1; i <= code_len; i++) {
src[i - 1] = data[i - 1];
}
//fix error
if (error)
src[error - 1] = '1' - src[error - 1] + '0';
j = 0;
for (i = 1; i <= code_len; i++) {
if (i & (i -1))
out[j++] = src[i - 1];
}
if (pout)
*pout = binstr2num(out);
return XOK;
}
int main(int argc, char *argv[])
{
xt_s32 a = 0;
xt_u8 str[32] = {0};
xt_u8 eout[32] = {0};
xt_u8 sout[32] = {0};
num2binstr(0xD3, str, 13);
printf("str=%s\n", str);
hammingCodeEncode(0xD3, 13, eout);
printf("code=%s\n", eout);
hammingCodeDecode("110100010110100011", 13, sout, &a);
printf("sout=%s, decode=%d\n", sout, a);
hammingCodeDecode("010100010110100011", 13, sout, &a);
printf("sout=%s, decode=%d\n", sout, a);
hammingCodeDecode("100100010110100011", 13, sout, &a);
printf("sout=%s, decode=%d\n", sout, a);
hammingCodeDecode("111100010110100011", 13, sout, &a);
printf("sout=%s, decode=%d\n", sout, a);
hammingCodeDecode("110000010110100011", 13, sout, &a);
printf("sout=%s, decode=%d\n", sout, a);
return XOK;
}