使用C语言模拟汉明码一位校验原理(根据输入位数自动确定偶校验公式)

数据校验

原因

数据在存储和传送过程中会发生错误,产生错误的原因有很多,例如外界高频干扰,除了提高硬件质量以外,还应该在数据编码上下文章

校验基础

当我们进行编码时,任意一个编码都由码字组成

例如用二进制表示16为10000,表示15为1111

任意两个码字之间最少变化的二进制的位数称为数据校验码的码距。

只有码距大于1时,才可以进行校验。这是因为码距为1的情况下,当一个合法码出现一位或者几位码字错误时,通常会变成另外一个合法码字。例如,使用4个二进制位表示0到15,此时的码距为1。但是如果使用4个二进制位表示0到3时,采用如下的编码方式:

字符二进制表示
00000
10101
20110
31001

此时的码距将变成2,当其中任何一个编码出现一位错误,从0变成1;或者从1变成0时,它将成为非法编码。此时我们就知道其出现错误。
校验的的原理就是在原有的编码中插入校验位,使码距大于1,这是最基本的要求,如果能使码距均匀的增大,如同上表所示时,校验的能力将进一步增强

编程实现汉明码校验逻辑

  1. 实现汉明码校验逻辑
  2. 模拟码字出现错误时,使用汉明码进行校验的结果

处理思路

根据有效的信息位数N和下面的公式求出校验码的位数K
2 K − 1 ≥ N + K + 1 2^{K-1}\geq N+K+1 2K1N+K+1
下表给出常用的信息位N和K之间的关系:

N值最小K值N值最小K值
1~3426~567
4~10557~1198
11~256

接下来将校验码插入到有效信息位当中,插入的规则是:

  1. 编号:将汉明码编号依次为 H m H m − 1 . . . H 2 H 1 H_mH_{m-1}...H_2H_1 HmHm1...H2H1
  2. 插入校验位:每个校验位 P i P_i Pi分到位号为 2 i − 1 2^{i-1} 2i1的位置上,当位置编号大于m时,改为m,其中 i = 0 , 1 , . . . i=0,1,... i=0,1,...
  3. 校验规则:汉明码的每一位 H i H_i Hi由多个校验位校验,其关系是被校验的每一位位号等于校验它的各校验位的位号之和,即汉明码的位号实质上是参与校验的各校验位权值之和。举例说明如下
    N=8时,K=5
    插入校验位以后变成:
    P 5    D 8    D 7    D 6    D 5    P 4    D 4    D 3    D 2    P 3    D 1    P 2    P 1 P_5 \ \ D_8 \ \ D_7 \ \ D_6 \ \ D_5 \ \ P_4 \ \ D_4\ \ D_3 \ \ D_2 \ \ P_3 \ \ D_1 \ \ P_2 \ \ P_1\\ P5  D8  D7  D6  D5  P4  D4  D3  D2  P3  D1  P2  P1
    使用 X i X_i Xi表示内容为 i 的位号,则有:
    X D 1 = 3 = X P 2 + X P 1 X D 2 = 3 = X P 3 + X P 1 X D 3 = 3 = X P 3 + X P 2 X D 4 = 3 = X P 3 + X P 2 + X P 1 X D 5 = 3 = X P 3 + X P 2 + X P 1 X D 6 = 3 = X P 4 + X P 2 X D 7 = 3 = X P 4 + X P 2 + X P 1 X D 8 = 3 = X P 4 + X P 3 \begin{align*} &X_{D_1}=3=X_{P_2}+X_{P_1}\\ &X_{D_2}=3 =X_{P_3}+X_{P_1}\\ &X_{D_3}=3 =X_{P_3}+X_{P_2}\\ &X_{D_4}=3 =X_{P_3}+X_{P_2}+X_{P_1}\\ &X_{D_5}=3 =X_{P_3}+X_{P_2}+X_{P_1}\\ &X_{D_6}=3 =X_{P_4}+X_{P_2}\\ &X_{D_7}=3 =X_{P_4}+X_{P_2}+X_{P_1}\\ &X_{D_8}=3 =X_{P_4}+X_{P_3} \end{align*} XD1=3=XP2+XP1XD2=3=XP3+XP1XD3=3=XP3+XP2XD4=3=XP3+XP2+XP1XD5=3=XP3+XP2+XP1XD6=3=XP4+XP2XD7=3=XP4+XP2+XP1XD8=3=XP4+XP3
  4. 收集:观察上面的等式,等式右边含有校验位 p 1 p_1 p1的等式左边对应的信息位,如下
    D 7    D 5    D 4    D 2    D 1 D_7 \ \ D_5 \ \ D_4 \ \ D_2 \ \ D_1 D7  D5  D4  D2  D1
    对上述位进行偶校验得到
    P 1 = D 7 ⨁ D 5 ⨁ D 4 ⨁ D 2 ⨁ D 1 P_1=D_7 \bigoplus D_5 \bigoplus D_4 \bigoplus D_2 \bigoplus D_1 P1=D7D5D4D2D1
  5. 根据上面分析,便可以得到完整的校验公式
    P 1 = D 1 ⨁ D 2 ⨁ D 4 ⨁ D 5 ⨁ D 7 P 2 = D 1 ⨁ D 3 ⨁ D 4 ⨁ D 6 ⨁ D 7 P 3 = D 2 ⨁ D 3 ⨁ D 4 ⨁ D 8 P 4 = D 5 ⨁ D 6 ⨁ D 7 ⨁ D 8 P_1=D_1 \bigoplus D_2 \bigoplus D_4 \bigoplus D_5 \bigoplus D_7\\ P_2=D_1 \bigoplus D_3 \bigoplus D_4 \bigoplus D_6 \bigoplus D_7\\ P_3=D_2 \bigoplus D_3 \bigoplus D_4 \bigoplus D_8 \\ P_4=D_5 \bigoplus D_6 \bigoplus D_7 \bigoplus D_8 \\ P1=D1D2D4D5D7P2=D1D3D4D6D7P3=D2D3D4D8P4=D5D6D7D8
    在上述公式中, D 4 , D 7 D_4,D_7 D4,D7出现了三次,而 D 1 , D 2 , D 3 , D 5 , D 6 , D 8 D_1,D_2,D_3,D_5,D_6,D_8 D1,D2,D3,D5,D6,D8仅出现了两次,为此再补充 P 5 P_5 P5
    P 5 = D 1 ⨁ D 2 ⨁ D 3 ⨁ D 5 ⨁ D 6 ⨁ D 8 P_5=D_1\bigoplus D_2\bigoplus D_3\bigoplus D_5\bigoplus D_6\bigoplus D_8 P5=D1D2D3D5D6D8
    此时任何一个信息位发生变化,必将引起3个 P i P_i Pi的值跟着改变,即合法的汉明码的码距都是4
    6.校验:将接收到的汉明码按如下的关系进行偶校验
    S 1 = P 1 ⨁ D 1 ⨁ D 2 ⨁ D 4 ⨁ D 5 ⨁ D 7 S 2 = P 2 ⨁ D 1 ⨁ D 3 ⨁ D 4 ⨁ D 6 ⨁ D 7 S 3 = P 3 ⨁ D 2 ⨁ D 3 ⨁ D 4 ⨁ D 8 S 4 = P 4 ⨁ D 5 ⨁ D 6 ⨁ D 7 ⨁ D 8 S 5 = P 5 ⨁ D 1 ⨁ D 2 ⨁ D 3 ⨁ D 5 ⨁ D 6 ⨁ D 8 S_1=P_1\bigoplus D_1 \bigoplus D_2 \bigoplus D_4 \bigoplus D_5 \bigoplus D_7\\ S_2=P_2\bigoplus D_1 \bigoplus D_3 \bigoplus D_4 \bigoplus D_6 \bigoplus D_7\\ S_3=P_3\bigoplus D_2 \bigoplus D_3 \bigoplus D_4 \bigoplus D_8 \\ S_4=P_4\bigoplus D_5 \bigoplus D_6 \bigoplus D_7 \bigoplus D_8 \\ S_5=P_5\bigoplus D_1\bigoplus D_2\bigoplus D_3\bigoplus D_5\bigoplus D_6\bigoplus D_8 S1=P1D1D2D4D5D7S2=P2D1D3D4D6D7S3=P3D2D3D4D8S4=P4D5D6D7D8S5=P5D1D2D3D5D6D8
  6. 结果分析:
    这里暂且只考虑一位发生错误的情况,因为在汉明码中同时发生两位和三位错误的概率很小。但是还是通过代码模拟了两位,三位甚至是多为发生错误的情况,但是发现和教材上有出入,然后我也发电子邮件给作者了。接下来就简单介绍一下纠错的过程。
    (1) S 5 S 4 S 3 S 2 S 1 S_5S_4S_3S_2S_1 S5S4S3S2S1为全0时,表明无错
    在这里插入图片描述
    (2) S 5 S 4 S 3 S 2 S 1 S_5S_4S_3S_2S_1 S5S4S3S2S1有三位不为0时,说明有一位信息位出错或者三位校验位出错,由于后一种可能性很小,通常都是前一种错误,出错的位号由 S 4 S 3 S 2 S 1 S_4S_3S_2S_1 S4S3S2S1这四位代码指明,此时不仅能检错,还可以纠错,将该位变反
    在这里插入图片描述

设计

!!!!!所使用的数组类型均自定义,其中0号单元不使用!!!!
1. getMessage方法:接收用户输入的有效的信息,使用message数组进行存储,根据用户的输入动态分配相应的存储空间
    8 16 32 64 128
2. computerCheckcode方法:计算校验码的位数:
    (1)根据公式进行计算,暂且保留2^(K-1)>=N+K+1,使用暴力法可以求出K值
    (2)直接查表计算
        N       K
        1~3     4
        4~10    5
        11~15   6
3. insertCheck方法:在对应位置插入校验位,初始的时候每个校验位值为0,插入的位置满足2^(i-1)
    1 2 4 8 16 32 ……最后一位
    重新申请K+N的空间,记为hamming
    使用变量index记录message里面元素移动到hamming数组里面的个数
    i从1开始递增,当2^i 小于等于hamming的长度时执行如下操作
        hamming[2^i]=0
        j从2^i+1递增到2^(i+1)-1
            hamming[j]=message[index++]
        i++

4. generateCheckcode方法:生成偶校验公式,一共有K(校验位的数目)个公式,每一个公式包含很多的异或运算

    定义DS二维数组(N+k)*(K)

    遍历一遍hamming数组
        在每一趟循环中,当前元素不是校验位时,计算下标(从1开始计数)对应的二进制代码,储存在DS数组的对应行

    定义PS二维数组:K*(N)
    Ps里面的第i行,存储的是pi校验位 校验的Di对应在hanmming数组(汉明码)里面的位置,举例说明
    p1校验位校验D1,D2,D4,D5,D7,它们在汉明数组里面的位置是3,5,7,9,11
    于是Ps数组第1行储存3,5,7,9,11

    定义counts数组,长度为N+K+1,0号单元不使用,count[i]表示在hammming数组中位置为i的信息为在校验公式中出现的次数

    处理DS数组
    按列的顺序从右往左遍历DS数组
        按行的方式从上到下遍历DS数组
            元素内容为1时
                记录当前位置的行坐标i在PS数组对应的位置,使用变量p表示下一记录的位置,记录完成之后p++
                counts[i]++
    遍历conts数组,找到最大值max
    遍历counts数组,如果count[i]<max&&count[i]不为0,使用P来记录下i在Ps第K行里面的位置,在p位置赋值,p++
    经过上述分析,所有的校验公式都已经生成

5. check方法:根据校验公式确定校验位
    申请空间为K的数组result,存储校验位
    遍历Ps数组
    遍历行,行标i
        遍历列,列标j
            进行异或运算:result.elems[0]=result.elems[0]异或hamming[Ps.elems[i][j]]
    返回result


6. insert方法:将上述返回的result(校验位插入到)填入hamming数组合适的位置(调用insert方法,实现思路和insertCheck方法类似)


7. simulation方法:模拟汉明码一位或者某几位出现错误,然后进行偶校验
    可以使用循环模拟1位,两位甚至是多位出错的情况

8. finish方法:输出校验的结果,一共有K位,其中K-1位为有效位,正确结果全为0
    接收正确的hamming数组hamming和突变后的errorCode
    对errorCode进行偶校验,即调用check方法,得到ds_checks
    对errorCode调用getCheck方法,返回在errorCode中所有的校验位ps_checks
    遍历ps_checks数组
        ds_checks[i]=ds_checks[i]异或ps_checks[i]
    打印输出相关信息

测试数据:
N=8
K=5
message=10101100 

详细代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

typedef struct
{

    int *elems;
    int length;
} Array;

typedef struct
{
    /* data */
    int **elems;
    int m;
    int n;
} Matrix;

/*
    !!!!!所使用的数组类型均自定义,其中0号单元不使用!!!!

    1. getMessage方法:接收用户输入的有效的信息,使用message数组进行存储,根据用户的输入动态分配相应的存储空间
        8 16 32 64 128
    2. computerCheckcode方法:计算校验码的位数:
        (1)根据公式进行计算,暂且保留2^(K-1)>=N+K+1,使用暴力法可以求出K值
        (2)直接查表计算
            N       K
            1~3     4
            4~10    5
            11~15   6
    3. insertCheck方法:在对应位置插入校验位,初始的时候每个校验位值为0,插入的位置满足2^(i-1)
        1 2 4 8 16 32 ……最后一位
        重新申请K+N的空间,记为hamming
        使用变量index记录message里面元素移动到hamming数组里面的个数
        i从1开始递增,当2^i 小于等于hamming的长度时执行如下操作
            hamming[2^i]=0
            j从2^i+1递增到2^(i+1)-1
                hamming[j]=message[index++]
            i++

    4. generateCheckcode方法:生成偶校验公式,一共有K(校验位的数目)个公式,每一个公式包含很多的异或运算

        定义DS二维数组(N+k)*(K)

        遍历一遍hamming数组
            在每一趟循环中,当前元素不是校验位时,计算下标(从1开始计数)对应的二进制代码,储存在DS数组的对应行

        定义PS二维数组:K*(N)
        Ps里面的第i行,存储的是pi校验位 校验的Di对应在hanmming数组(汉明码)里面的位置,举例说明
        p1校验位校验D1,D2,D4,D5,D7,它们在汉明数组里面的位置是3,5,7,9,11
        于是Ps数组第1行储存3,5,7,9,11

        定义counts数组,长度为N+K+1,0号单元不使用,count[i]表示在hammming数组中位置为i的信息为在校验公式中出现的次数

        处理DS数组
        按列的顺序从右往左遍历DS数组
            按行的方式从上到下遍历DS数组
                元素内容为1时
                    记录当前位置的行坐标i在PS数组对应的位置,使用变量p表示下一记录的位置,记录完成之后p++
                    counts[i]++
        遍历conts数组,找到最大值max
        遍历counts数组,如果count[i]<max&&count[i]不为0,使用P来记录下i在Ps第K行里面的位置,在p位置赋值,p++
        经过上述分析,所有的校验公式都已经生成

    5. check方法:根据校验公式确定校验位
        申请空间为K的数组result,存储校验位
        遍历Ps数组
        遍历行,行标i
            遍历列,列标j
                进行异或运算:result.elems[0]=result.elems[0]异或hamming[Ps.elems[i][j]]
        返回result


    6. insert方法:将上述返回的result(校验位插入到)填入hamming数组合适的位置(调用insert方法,实现思路和insertCheck方法类似)


    7. simulation方法:模拟汉明码一位或者某几位出现错误,然后进行偶校验
        可以使用循环模拟1位,两位甚至是多位出错的情况

    8. finish方法:输出校验的结果,一共有K位,其中K-1位为有效位,正确结果全为0
        接收正确的hamming数组hamming和突变后的errorCode
        对errorCode进行偶校验,即调用check方法,得到ds_checks
        对errorCode调用getCheck方法,返回在errorCode中所有的校验位ps_checks
        遍历ps_checks数组
            ds_checks[i]=ds_checks[i]异或ps_checks[i]
        打印输出相关信息

    测试数据:
    N=8
    K=5
    message=10101100
*/
/************************************数组,二维数组基础操作************************************************************/
void initArray(Array &array, int length)
{
    array.length = length;
    array.elems = (int *)malloc(sizeof(int) * (length + 1));
    for (int i = 1; i <= length; i++)
    {
        /* code */
        array.elems[i] = 0;
    }
}

void copyArray(Array origin, Array &target)
{
    initArray(target, origin.length);
    for (int i = 1; i <= origin.length; i++)
    {
        target.elems[i] = origin.elems[i];
    }
}

void printArray(Array array)
{

    for (int i = array.length; i >= 1; i--)
    {
        printf("%d\t", array.elems[i]);
    }
    printf("\n");
    for (int i = array.length; i >= 1; i--)
    {
        printf("%d\t", i);
    }
    printf("\n");
}

void initMatrix(Matrix &martrix, int m, int n)
{
    martrix.elems = (int **)malloc(sizeof(int *) * (m + 1));
    for (int i = 1; i <= m; i++)
    {
        int *row = (int *)malloc(sizeof(int) * (n + 1));
        for (int j = 1; j < n + 1; j++)
        {
            row[j] = 0;
        }
        martrix.elems[i] = row;
    }
    martrix.m = m;
    martrix.n = n;
}

void printMataix(Matrix matrix)
{

    for (int i = 1; i <= matrix.m; i++)
    {
        for (int j = 1; j <= matrix.n; j++)
        {
            /* code */
            printf("%d ", matrix.elems[i][j]);
        }
        printf("\n");
    }
}
/************************************业务逻辑************************************************************/
// 接收用户输入的有效的信息,使用message数组进行存储
void getMessage(Array &array)
{
    int length;
    printf("输入有效的信息的位数:\n");
    scanf("%d", &length);
    printf("输入有效的信息,中间使用空格区分信息元素:\n");
    initArray(array, length);
    for (int i = length; i >= 1; i--)
    {
        scanf("%d", &array.elems[i]); // 接收输入
    }
}
// 计算校验码的位数
int computerCheckCode(int N)
{
    if (N >= 1 && N <= 3)
    {
        return 4;
    }
    else if (N <= 10)
    {
        return 5;
    }
    else if (N < 15)
    {
        return 6;
    }
    else
    {
        // 根据公式进行计算,暂且保留2^(K-1)>=N+K+1,使用暴力法可以求出K值
        int K = 7;
        while (2 ^ (K - 1) < N + K + 1)
        {
            K++;
        }
        return K;
    }
}
// 在对应位置插入校验位,初始的时候每个校验位值为0,插入的位置满足2^(i-1)
void insertCheck(Array message, int K, Array &hamming)
{
    int length = message.length + K;
    initArray(hamming, length);
    int i = 1;
    int index = 1;
    hamming.elems[1] = 0;
    while (pow(2, i) < length)
    {
        int p = pow(2, i); // 插入校验位
        hamming.elems[p] = 0;
        int left = p + 1;
        int right = 2 * p - 1;
        if (right > length)
        {
            right = length - 1;
        }
        if (right >= left)
        {
            for (int j = left; j <= right; j++)
            {
                hamming.elems[j] = message.elems[index];
                index++;
            }
        }
        i++;
    }
    hamming.elems[length] = 0; // 汉明码最高位为校验位
}
// 内部调用函数,返回x所对应的二进制位,使用数组存储,长度为k,二进制最高位储存在1号单元
// x=5,k=5时00101
// x=4,k=3时0011
Array binary(int x, int k)
{
    Array result;
    initArray(result, k);

    while (x != 0)
    {
        /* code */
        int temp = x % 2;
        x = x / 2;
        result.elems[k--] = temp;
    }
    return result;
}
// 内部调用函数,返回数组最大值
int findMax(int array[], int l, int r)
{

    int result = array[l];
    for (int i = l + 1; i <= r; i++)
    {
        if (result < array[i])
        {
            result = array[i];
        }
    }
    return result;
}
// 生成偶校验公式,一共有K(校验位的数目)个公式,每一个公式包含很多的异或运算
void generateCheck(Matrix &Ds, int N, int K, Matrix &Ps, Array hamming)
{

    // 定义DS二维数组(N + k) *(K)
    // 定义PS二维数组:K *(N)
    initMatrix(Ds, N + K, K);
    initMatrix(Ps, K, N + K);
    // Ps里面的第i行,存储的是pi校验位 校验的Di对应在hanmming数组(汉明码)里面的位置,举例说明
    //     p1校验位校验D1,
    //     D2, D4, D5, D7,它们在汉明数组里面的位置是3,5,7,9,11 于是Ps数组第1行储存3,5,7,9,11 int count[N + K + 1];

    int i = 1;
    int index = 1;
    do
    {

        int left = pow(2, i) + 1;
        int right = pow(2, i + 1) - 1;
        if (right > hamming.length - 1)
        {
            right = hamming.length - 1;
        }
        // 在每一趟循环中,当前元素不是校验位时,计算下标(从1开始计数)对应的二进制代码,储存在DS数组的对应行
        for (int j = left; j <= right; j++)
        {
            Ds.elems[j] = binary(j, K).elems;
            index++;
        }
        i = i + 1;
    } while (index <= N);

    int count[N + K + 1]; // 0号单元不使用,count [i] 表示在hammming数组中位置为i的信息为在校验公式中出现的次数
    for (int i = 1; i < N + K + 1; i++)
    {
        count[i] = 0;
    }
    // 按列的顺序从右往左遍历DS数组
    for (int j = K; j >= 1; j--)
    {
        int p = 1;
        // 按行的方式从上到下遍历DS数组
        for (int i = 1; i <= N + K; i++)
        {

            if (Ds.elems[i][j] == 1)
            {
                // 记录当前位置的行坐标i在PS数组对应的位置,使用变量p表示下一记录的位置,记录完成之后p++ counts[i]++
                Ps.elems[K - j + 1][p++] = i;
                count[i]++;
            }
        }
    }
    int max = findMax(count, 1, N);
    int k = 1;
    for (int i = 1; i < N + K + 1; i++)
    {
        if (count[i] < max && count[i] != 0)
        {
            // 遍历counts数组,如果count[i] < max &&count[i] 不为0
            // 使用P来记录下i在Ps第K行里面的位置,在p位置赋值,p++
            Ps.elems[K][k++] = i;
        }
    }
}

//内部函数,实现两位的异或运算
int xOr(int a, int b)
{
    return (!a & b) | (!b & a);
}

// 开始根据偶校验公式校验计算,连环的异或运算
Array check(Array hamming, Matrix Ps)
{

    Array result;
    initArray(result, Ps.m);
    for (int i = 1; i <= Ps.m; i++)
    {

        for (int j = 1; j <= Ps.n && Ps.elems[i][j] != 0; j++)
        {
            // 进行异或运算:result.elems[0]=result.elems[0]异或hamming[Ps.elems[i][j]]
            result.elems[i] = xOr(result.elems[i], hamming.elems[Ps.elems[i][j]]);
        }
    }
    return result;
}

//进行total次处理,每次处理随机选取一位从0变1或从1变0
Array simulation(Array hamming, int total)
{
    Array copy;
    copyArray(hamming, copy);
    srand((unsigned)time(NULL));
    for (int i = 1; i <= total; i++)
    {
        int a = rand();
        int position = a % (hamming.length - 1 + 1) + 1;
        if (i == 1)
        {
            copy.elems[position] = !hamming.elems[position];
        }
        else
        {
            copy.elems[position] = !copy.elems[position];
        }
    }
    return copy;
}

//指定位置的突变,使用数组记录突变的位置
Array simulation(Array hamming, int chagePositions[], int n)
{
    Array copy;
    copyArray(hamming, copy);
    for (int i = 0; i < n; i++)
    {
        copy.elems[chagePositions[i]] = !hamming.elems[chagePositions[i]];
    }
    return copy;
}
// 内部函数插入根据校验公式生成的校验位
void insert(Array &hamming, Array check)
{

    hamming.elems[1] = check.elems[1];
    int i = 1;
    while (i <= check.length - 1)
    {
        int p = pow(2, i);
        if (p > hamming.length)
        {
            p = hamming.length;
        }
        hamming.elems[p] = check.elems[i + 1];
        i++;
    }
}
// 内部函数获取校验位
Array getCheck(Array hamming, int K)
{

    Array result;
    initArray(result, K);
    result.elems[1] = hamming.elems[1];
    int i = 1;
    while (i <= K - 1)
    {
        /* code */
        int p = pow(2, i);
        if (p > hamming.length)
            p = hamming.length;
        result.elems[++i] = hamming.elems[p];
    }
    return result;
}

// 最终检查,校验
void finish(Array hamming,Array errorCode, Matrix Ps)
{

    Array ps_checks = getCheck(errorCode, Ps.m);
    Array ds_checks = check(errorCode, Ps);
    printf("输出正确的结果:\n");
    printArray(hamming);
    for (int i = 1; i <= ps_checks.length; i++)
    {
        ps_checks.elems[i] = xOr(ps_checks.elems[i], ds_checks.elems[i]);
    }
    printf("模拟出现错误的结果:\n");
    printArray(errorCode);
    printf("S5到S1为:\n");
    printArray(ps_checks);
}

// 辅助的测试函数,生成测试用例
/*
    10101100
    N=8
    K=5
*/
void test(Array &message)
{
    int array[] = {0, 0, 1, 1, 0, 1, 0, 1};
    int N = 8;
    initArray(message, N);
    for (int i = 1; i <= message.length; i++)
    {
        message.elems[i] = array[i - 1];
    }
}

int main()
{
    Array message;
    // getMessage(message);
    // Array message;
    test(message);
    printf("原始的信息为:\n");
    printArray(message);

    int N = message.length;       // 有效信息D的位数
    int K = computerCheckCode(N); // 校验位P的位数

    // 生成和插入校验位
    Array hamming;
    insertCheck(message, K, hamming);

    // 进行偶校验计算
    Matrix Ds; // 辅助的二维数组
    Matrix Ps;
    // Ps和Ds初始化时,里面所有的元素为1
    // Ps里面的第i行,存储的是pi校验位校验的Di对应在hanmming数组(汉明码里面的位置),举例说明
    //  p1校验位校验D1,D2,D4,D5,D7,它们在汉明数组里面的位置是3,5,7,9,11
    //  于是Ps数组第i行储存3,5,7,9,11
    // 下面的generateCheck函数实现上述功能
    printf("\n");
    generateCheck(Ds, N, K, Ps, hamming);
    // 检验操作
    /*
        1. 指定突变的位置
        2. 在hamming数组进行100次处理,每次随机选择选择一位取反
    */
    Array correct = check(hamming, Ps);
    printf("生成的校验位为:\n");
    printArray(correct);
    insert(hamming, correct);

    // 指定突变位置
    int positions[] = {7};
    Array errorCode = simulation(hamming, positions, 1);
    // 在hamming数组进行100次处理,每次随机选择选择一位取反
    // errorCode = simulation(hamming, 100);
    // 输出最终的校验结果
    finish(hamming, errorCode, Ps);
    // finish(hamming, hamming, Ps);//模拟未出错的情况

    return 0;
}

使用说明

进入main函数,修改相关位置代码即可,有详细的注释。

    // 指定突变位置
    int positions[] = {7};
    Array errorCode = simulation(hamming, positions, 1);
    // 在hamming数组进行100次处理,每次随机选择选择一位取反
    // errorCode = simulation(hamming, 100);
    // 输出最终的校验结果
    finish(hamming, errorCode, Ps);
    // finish(hamming, hamming, Ps);//模拟未出错的情况

邮件回复

在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值