循环冗余校验码(CRC码)

循环冗余校验码(CRC码)

循环冗余校验码的思想:
数据发送、接受方约定一个“除数”
K个信息位+R个校验位作为“被除数”,添加校验位后需保证除法的余数为0。收到数据后,进行除法检查余数是否为0,若余数非0说明出错,则进行重传或纠错。
在这里插入图片描述
例.设生成多项式为G(x)=x 3 x^3x3+x 2 x^2x2+1,信息码为101001,求对应CRC码。

1.确定K、R以及生成多项式对应的二进制码

K=信息码的长度=6,R=生成多项式最高次幂=3——>校验码位数N=K+R=9
生成多项式G(x)=1*x 3 x^3x3+1*x 2 x^2x2+0*x 1 x^1x1+1*x 0 x^0x0,对应二进制码1101

2.移位

信息码左移R位,低位补0。(101001000

3.相除

对移位后的信息码,用生成多项式进行模2除法,产生余数

模2除法

在这里插入图片描述
对应的CRC码:101001 001

4.检错和纠错

发送:101001001 记为C 9 C_9C9C 8 C_8C8C 7 C_7C7C 6 C_6C6C 5 C_5C5C 4 C_4C4C 3 C_3C3C 2 C_2C2C 1 C_1C1
接收:101001001 ———> 用110进行模2除——> 余数为000,代表没有出错。

K个信息位,R个校验位,若生成多项式选择得当,且2 R 2^R2R>=K+R+1,则CRC码课纠正1位错。(实际应用中一般只用来“检错”)

理论上可以正面循环冗余校验码的检错能力有以下特点:
1.可检测出所有奇数个错误;
2.可检测出所有双比特的错误;
3.可检测出所有小于等于校验位长度的连续错误

以下一个小例子:

/**
     * 计算CRC16校验码
     *
     * @param bytes
     * @return
     * [1,3,4,1,205,1,18,235,173]
     */
    public static String CRC16(byte[] bytes) {
        int CRC = 0x0000ffff;
        int POLYNOMIAL = 0x0000a001;
        int i, j;
        for (i = 0; i < bytes.length; i++) {
            CRC ^= ((int) bytes[i] & 0x000000ff);
            for (j = 0; j < 8; j++) {
                if ((CRC & 0x00000001) != 0) {
                    CRC >>= 1;
                    CRC ^= POLYNOMIAL;
                } else {
                    CRC >>= 1;
                }
            }
        }
        return Integer.toHexString(CRC);
    }


     public static void main(String[] args) {
        byte[] s ={1,3,4,1,(byte) 205,1,18,(byte)235,(byte)173};

         System.out.printf("1111%s\r\n",CRC16(s));
        if (CRC16(s)!="00"){
            System.out.printf("2222%s\n",CRC16(s));
        }
    }

版权声明:本文为DTRblank原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。