海明码 OR 汉明码(Hamming Code) C语言

#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;
}

You may also like...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据