📜  Hamming代码在C C++中的实现(1)

📅  最后修改于: 2023-12-03 15:31:06.004000             🧑  作者: Mango

Hamming代码在C/C++中的实现

概述

Hamming是一种用于错误检测和纠正的编码技术。它可以检测和纠正数据传输中可能发生的错误。在计算机网络和通信领域广泛应用。

在本文中,我们将介绍如何在C/C++中实现Hamming编码和解码。我们首先介绍Hamming编码和解码的原理,然后给出C/C++实现的代码,最后进行一些简单的示例演示。

原理

Hamming码是通过为传输的数据添加冗余数据来实现错误检测和纠正的。冗余数据是通过在原始数据中插入若干个冗余位来生成的。冗余位的数量取决于数据位的数量。

Hamming码的基本原理是将数据位排列在一个矩形阵列中,然后在矩形阵列的行和列上添加冗余位。在传输数据时,发送方会发送原始数据和冗余位,接收方会使用冗余位检测和纠正可能的错误。

在Hamming编码中,数据位和校验位共同组成了一个二进制码,称为Hamming码。Hamming码的一般表示方式为H(n,k),其中n表示码字总位数,k表示信息位的数量,r=n-k表示校验位的数量。Hamming码的每一个校验位都与一个或多个数据位相关联,当数据位发生错误时,会影响关联的校验位,从而导致检测和纠正错误。

C/C++实现

我们将首先给出C++实现的代码。

#include<bits/stdc++.h>
using namespace std;

int main(){
    int k=4;//信息位数量
    int n=7;//码字总长度
    int code[11];//存储编码后的数据

    //获取信息位数组a
    int a[k];
    cout<<"请输入"<<k<<"个信息位:\n";
    for(int i=0;i<k;i++)
        cin>>a[i];

    //计算校验位数量r
    int r=0;
    while((1<<r)<k+r+1)r++;//求2^(r)>=k+r+1

    //计算码字长度n和校验位的位置pos
    int pos=0;
    for(int i=0;i<n;i++){
        if(i+1==1<<pos){//如果是2^i位置,则增加一个校验位
            code[i]=-1;  //先占位
            pos++;
        }
        else code[i]=a[i-pos];
    }

    //计算每个校验位的值并填入编码后的数据
    for(int i=0;i<r;i++){
        int bit=1<<i;//获取校验位的位置
        int v=0;//计算校验位的值
        for(int j=0;j<n;j++){
            if(j&bit)v^=code[j];
        }
        code[bit-1]=v;
    }

    //输出最终的编码结果
    cout<<"编码后的数据如下:\n";
    for(int i=0;i<n;i++)
        cout<<code[i]<<" ";
    cout<<"\n";

    return 0;
}

上面的代码实现了对k个信息位进行r个校验位的Hamming编码。首先从标准输入读入k个信息位,并计算出r。然后根据信息位计算出各个校验位的值,并存储在编码后的数据中。

接下来,我们给出C实现的代码。

#include<stdio.h>

int main(){
    int k=4;//信息位数量
    int n=7;//码字总长度
    int code[11];//存储编码后的数据

    //获取信息位数组a
    int a[k];
    printf("请输入%d个信息位:\n",k);
    for(int i=0;i<k;i++)
        scanf("%d",&a[i]);

    //计算校验位数量r
    int r=0;
    while((1<<r)<k+r+1)r++;//求2^(r)>=k+r+1

    //计算码字长度n和校验位的位置pos
    int pos=0;
    for(int i=0;i<n;i++){
        if(i+1==1<<pos){//如果是2^i位置,则增加一个校验位
            code[i]=-1;  //先占位
            pos++;
        }
        else code[i]=a[i-pos];
    }

    //计算每个校验位的值并填入编码后的数据
    for(int i=0;i<r;i++){
        int bit=1<<i;//获取校验位的位置
        int v=0;//计算校验位的值
        for(int j=0;j<n;j++){
            if(j&bit)v^=code[j];
        }
        code[bit-1]=v;
    }

    //输出最终的编码结果
    printf("编码后的数据如下:\n");
    for(int i=0;i<n;i++)
        printf("%d ",code[i]);
    printf("\n");

    return 0;
}

这个C语言的代码与C++版本几乎相同,只有一些输入输出方面的不同。

示例

为了演示Hamming编码和解码的过程,我们考虑一个简单的例子。

例如,我们要对1011进行Hamming编码。根据上面C++代码的实现,我们可以得到编码后的数据:1 0 1 -1 1 0 0。这个编码后的数据表示7位二进制码字,其中第1、3、5、7位是校验位,-1表示占位,第2、4、6位是数据位。

然后,我们考虑在传输中可能发生的错误。假设第1位出错,修改为0,那么我们得到的数据为0 0 1 -1 1 0 0。这时,我们可以使用校验位来检测并纠正错误。

首先,我们计算出每个校验位所涵盖的数据位。对于第1位,它覆盖了第1、3、5、7位的数据。然后,我们对这些数据位进行计算,得到校验位的值。对于第1个校验位,它包含了第1、3、5、7位,约定为B1,则校验位的值为B1=0+1+0+0=1。对于第2个校验位,它包含了第2、3、6、7位,约定为B2,则校验位的值为B2=0+1+0+0=1。

接下来,我们根据校验位值确定哪一个数据位出错,并进行纠正。对于第1个校验位,如果发现它的值不为1,说明第1、3、5、7位中至少有一个出错了,我们可以将二进制码的第1位修正为B1的值,即0->1。然后再次对数据进行检查,发现这个修改后的数据符合所有的校验位,因此,这个错误已经被正确地检测和纠正了。

这个简单的示例说明了Hamming编码的基本原理和应用。通过使用冗余位进行错误检测和纠正,Hamming编码可以在数据传输中保证传输的可靠性。