汉明码与交织技术

汉明码:

汉明码是由Richard Hanming于1950年提出的,它具有一位纠错能力。

设欲检测的二进制数据为n位,为使其具有纠错能力,需增添k位检测位,组成n+k位的数据。为了能准确对错误定位以及指出数据没错,新增添的检测位数k应满足:

2k≥n+k+1

由此关系求得不同数据长度n所需检测位的位数k,如下表:

数据长度与检测位位数的关系

n

k(最小)

1

2

2~4

3

5~11

4

12~26

5

27~57

6

58~120

7

k确定后,便可由它们所承担的检测任务设定它们在编程后的数据中的位置及取值。

设n+k位编码后的数据自左至右依次编号为第1,2,3,…,n+k位,而将k位检测位记作Ci(i=1,2,4,8,…),分别安插在第1,2,4,8,…,2k-1位上。这些检测位的位置设置是为了保证它们能分别承担n+k位数据中不同数位所组成的“小组”的奇偶检测任务,使检测位和它负责检测的小组中1的个数为奇数或为偶数,具体分配如下:

C1检测的g1小组包含第1,3,5,7,9,11,…位

C2检测的g2小组包含第2,3,6,7,10,11,14,15,…位

C3检测的g3小组包含第4,5,6,7,12,13,14,15,…位

C4检测的g4小组包含第8,9,10,11,12,13,14,15,24,…位

这种小组的划分具有如下特点:

1)每个小组gi有一位且仅有一位为它独占,即gi小组独占第2i-1位(i=1,2,3,…)

2)每两个小组gi和gj共同占有一位是其他小组没有的,即每两个小组gi和gj共同占有第2i-1+2j-1位(i,j=1,2,3…)

3)每三个小组gi、gj和gk共同占有第2i-1+2j-1+2k-1位,是其他小组没有的

依次类推,便可确定每组所包含的各位。

以n=4, k=3为例,数据为b4b3b2b1,它们的位置安排如下:

二进制序号

1    2    3    4    5    6    7

名称

 C1   C2   b4   C4    b3   b2    b1

如果按偶原则来配置汉明码,则C1应使第1,3,5,7位中“1”的个数为偶数,C2应使第2,3,6,7位中的“1”的个数为偶数,C4应使第4,5,6,7位中的“1”的个数为偶数。

令b4b3b2b1=0101,则:

C1= b4xor b3xor b1 = 0xor 1 xor 1 = 0

C2= b4xor b2xor b1 = 0xor 0 xor 1 = 1

C4= b3xor b2xor b1 = 1xor 0 xor 1 = 0

故对数据0101进行汉明码编码后为C1C2b4C4b3b2b1,即0100101。

汉明码的纠错过程实际上是对汉明码编码后的数据形成新的检测位Pi(i=1,2,4,8,…),根据Pi的状态,便可直接指出错误的位置。同样的,以n=4, k=3为例。

P1= C1xor b4xor b3xor b1

P2= C2xor b4xor b2xor b1

P4= C4xor b3xor b2xor b1

若正确汉明码为0100101,出错后的数据为0100111,则计算得到P4P2P1=110,这表示第6位出错了,于是我们将第6位由“1”改成“0”,便得到纠错后的正确数据。

交织技术:

对于每一个数据帧,汉明码可以纠正一位随机错误,但对于突发性的集中错误无能为力。为了解决这个问题,我们使用交织技术将突发性的集中错误转换成随机错误来解决。

交织是把经过汉明码编码的数据矩阵进行转置操作后,对数据进行重新排列,不添加冗余比特。

使用汉明码编码之后的秘密信息矩阵为:

C11C12b14C14b13b12b11

C21C22b24C24b23b22b21

C31C32b34C34b33b32b31

C41C42b44C44b43b42b41

 

进行交织编码之后的秘密信息矩阵为:

C11

C12

b14

C14

b13

b12

b11

C21

C22

b24

C24

b23

b22

b21

C31

C32

b34

C34

b33

b32

b31

C41

C42

b44

C44

b43

b42

b41

当发生集中错误时,如b14b24b34b44这4个连续的比特位均出错时,由于进行了交织编码,这4个连续的比特位实际上分别属于4个不同的汉明码,于是我们可以利用汉明码的纠错能力将这次的集中错误修复。

算法整体流程:

原文->汉明编码->交织编码->处理后的信息

传输

收到的信息->反交织编码->汉明码译码并纠错->原文

代码如下:

原文放在1.txt中.

#include 
#include 

//(7,4)hamming code encode
char hammingEncode(char ori)
{
    char b4,b3,b2,b1;
    b4=(ori&8)>>3;
    b3=(ori&4)>>2;
    b2=(ori&2)>>1;
    b1=ori&1;
    char c1,c2,c4;
    c1=b4^b3^b1;
    c2=b4^b2^b1;
    c4=b3^b2^b1;
    //最高位不用
    char output=0;
    output+=c1<<6;
    output+=c2<<5;
    output+=b4<<4;
    output+=c4<<3;
    output+=b3<<2;
    output+=b2<<1;
    output+=b1;
    return output;
//    fwrite(&output,1,1,fp);
}

//(7,4)hamming code decode
char hammingDecode(char enc,char flag)
{
    char c1,c2,b4,c4,b3,b2,b1;
    char output=0;
    c1=(enc&64)>>6;
    c2=(enc&32)>>5;
    b4=(enc&16)>>4;
    c4=(enc&8)>>3;
    b3=(enc&4)>>2;
    b2=(enc&2)>>1;
    b1=enc&1;
    char p1,p2,p4;
    p1=c1^b4^b3^b1;
    p2=c2^b4^b2^b1;
    p4=c4^b3^b2^b1;
    int errorIndex=p4*4+p2*2+p1;
    if(errorIndex)printf("error happen !\n");
    switch(errorIndex)
    {
    case 3:
        b4=(b4>0?0:1);
        break;
    case 5:
        b3=(b3>0?0:1);
        break;
    case 6:
        b2=(b2>0?0:1);
        break;
    case 7:
        b1=(b1>0?0:1);
        break;
    default:
        printf("pass!\n");
    }
    if(flag==0)//高4位
    {
        output+=b4<<7;
        output+=b3<<6;
        output+=b2<<5;
        output+=b1<<4;
    }
    else//低4位
    {
        output+=b4<<3;
        output+=b3<<2;
        output+=b2<<1;
        output+=b1;
    }
    return output;
}
//交织
void Interweave(char *buf,int len)
{
    int i,j;
    char *result=malloc(len);
    int bitIndex=7;
    unsigned char ch=0;
    int resultIndex=0;
    //先取最高位,依次收集
    for(i=7; i>=0; i--)
    {
        for(j=0; j>i)&1)<=0; j--)
        {
            result[curIndex++]+=((buf[i]>>j)&1)<>4);
        buf[curIndex++]=hammingEncode(ch&15);
    }
    fclose(fs);
    //交织编码
    Interweave(buf,curIndex);
    fwrite(buf,1,curIndex,fp);
    fclose(fp);
    free(buf);
}

void decode()
{
    FILE *fs,*fp;
    int i;
    //解密
    fs=fopen("2.txt","r");
    fp=fopen("3.txt","w");
    fseek(fs,0L,SEEK_END);
    int fileLen=ftell(fs);
    char *buf=malloc(fileLen);
    fseek(fs,0L,SEEK_SET);
    fread(buf,1,fileLen,fs);
    fclose(fs);
    //反交织编码
    RInterweave(buf,fileLen);
    char flag=0;
    char output=0;
    for(i=0; i


你可能感兴趣的:(数据恢复)