计算机网络——CRC校验码的简单测试

目录

  • 循环冗余校验码
  • 简单例子
  • 程序代码
  • 运行结果

循环冗余校验码

了解CRC校验

简单例子

实际的CRC校验码生成是采用二进制的模2算法(即减法不借位、加法不进位)计算出来的,这是一种异或操作。下面通过一些例子来进一步解释CRC的基本工作原理。假设:
(1)设约定的生成多项式为G(x)=x4+x+1,其二进制表示为10011,共5位,其中k=4。
(2)假设要发送数据序列的二进制为101011(即f(x)),共6位。
(3)在要发送的数据后面加4个0(生成f(x)*xk),二进制表示为1010110000,共10位。
(4)用生成多项式的二进制表示10011去除乘积1010110000,按模2算法求得余数比特序列为0100(注意余数一定是k位的)。
(5)将余数添加到要发送的数据后面,得到真正要发送的数据的比特流:1010110100,其中前6位为原始数据,后4位为CRC校验码。
(6)接收端在接收到带CRC校验码的数据后,如果数据在传输过程中没有出错,将一定能够被相同的生成多项式G(x)除尽,如果数据在传输中出现错误,生成多项式G(x)去除后得到的结果肯定不为0。 

程序代码


import java.util.Scanner;

/*
*
*  author: Zou WenXiang
*  version: 1.0
*  tool:Windows 10 Editplus5.2 JDK1.8.0
*/
public class CRCCheckTest {

    private static int counts = 1; // Used to record the number of modulo 2 operations.
    public static int[] checkBitArray = {1,0,1,0,0,1}; // Used to store the binary bit sequence of polynomials.
    public static void main(String[] args) {

        // Get user input through the Scanner class.
        // Create a Scanner object.
        Scanner scan = new Scanner(System.in);
        CRCCheckTest test = new CRCCheckTest();

        System.out.println("Multivariate equations based on known conventions : \n G(x) = x^5 + x^3 + x^0 , \n obtain the corresponding bit sequence of the generator polynomial.");
        System.out.println("The number of bits in the generator polynomial:");
        for(int item : checkBitArray){
            System.out.printf("%d ", item);
        }

        System.out.println("\nNote that you can only enter 0 1.\nPlease enter 0 1 string you want to transfer:");

        // Receive 0 1 string from the keyboard.
        String sourceData = scan.next();
        System.out.println("\"" + sourceData + "\"");
        scan.close();

        int sceLen = sourceData.length();
        int[] sourceBinaryNum = new int[sceLen]; // Used to store the binary data stream to be transferred.

        System.out.println("Output converted binary number:");
        System.out.printf("\"%s\"--->", sourceData);
        sourceBinaryNum = test.getBinaryNumbers(sourceData);
        System.out.println();

        int[] comp = new int[sourceBinaryNum.length + checkBitArray.length - 1];
        comp = test.compareTransBit(sourceBinaryNum, checkBitArray);

        int[] tempArr = test.moduloSecordOperation(comp, checkBitArray);
        System.out.println();
        tempArr = test.removeInvalidZero(tempArr);

        int remainderLen = tempArr.length;
        int[] tmp = tempArr;
        while(remainderLen >= checkBitArray.length){
            tmp = test.moduloSecordOperation(tempArr, checkBitArray);
            System.out.println();
            tempArr = test.removeInvalidZero(tmp);
            remainderLen = tempArr.length;
        }

        int[] result = new int[sourceBinaryNum.length + tempArr.length];
        int index = 0;
        System.out.println("The length of sourceBinaryNum-->" + sourceBinaryNum.length);
        for(int i = 0; i < sourceBinaryNum.length; i++){
            result[index] = sourceBinaryNum[i];
            System.out.printf("%d ", sourceBinaryNum[i]);
            index++;
        }
        System.out.println();

        System.out.println("The length of remainder-->" + tempArr.length);
        for(int i = 0; i < tempArr.length; i++){
            result[index] = tempArr[i];
            System.out.printf("%d ", tempArr[i]);
            index++;
        }
        System.out.println();

        System.out.println("The length of result is:" + result.length);
        for(int res = 0; res < result.length; res++){
            System.out.printf("%d ", result[res]);
        }

        long sum1 = test.convertBinaryToDecimal(result);
        System.out.println("\nsum1 :" + sum1);

        System.out.println("The binary bit sequence of polynomial");
        for(int k : checkBitArray){
            System.out.printf("%d ", k);
        }

        long sum2 = test.convertBinaryToDecimal(checkBitArray);
        System.out.println("\nsum2 :" + sum2);
        System.out.println();

        boolean bool = test.checkTransmission(sum1, sum2);
        System.out.println("The result is: sum1 % sum2 = " + sum1 % sum2 + " , " + bool);
        if(bool){
            System.out.println("  Successful congratulations ^_^");
        }else{
            System.out.println("  failure V_V!");
        }
    }
    // Convert 0 1 string to binary numbers.
    public static int[] getBinaryNumbers(String s){

        int sLen = s.length();
        int[] binaryNum = new int[sLen];

        for(int i = 0; i < sLen; i++){
            binaryNum[i] = s.charAt(i) - '0';
        }

        // System.out.printf("\"%s\"--->\n", s);
        System.out.printf(" ");
        for(int j : binaryNum){
            System.out.printf("%d ", j);
        }
        System.out.println();

        return binaryNum;
    }
    // Compare the data to be transmitted with the length of the bit sequence generated by the polynomial.
    public static int[] compareTransBit(int[] arr1, int[] arr2){

        int i = arr2.length - 1;
        int[] newArr = new int[arr1.length + i];
        int k = 0;
        for(int item = 0; item < arr1.length; item++){
            newArr[k] = arr1[item];
            k++;
        }
        while(i > 0){
            newArr[k] = 0;
            k++;
            i--;
        }

        for(int item : newArr){
            System.out.printf("%d ",item);
        }

        return newArr;

    }
    // Perform modulo 2 operation or XOR operation.
    public static int[] moduloSecordOperation(int[] arr1, int[] arr2){

        // int[] arrResult = new int[arr1.length]; // Used to store the remainder

        System.out.printf("\nThe %d XOR operation or modulo 2 operation:\n", counts);
        counts++;
        System.out.printf(" ");
        for(int index1 : arr1){
            System.out.printf(" %d", index1);
        }

        System.out.print("\n^");
        for(int index2 : arr2){
            System.out.printf(" %d", index2);
        }

        for(int i = 0; i < arr2.length; i++){
            arr1[i] = arr1[i] ^ arr2[i];
        }

        // System.out.println("\nAfter modulo 2 operation arr1:");
        System.out.printf("\n___________________________________________\n");
        System.out.printf(" ");
        for(int index1 : arr1){
            System.out.printf(" %d", index1);
        }

        // return arrResult;
        System.out.println();
        return arr1;

    }
    // Remove invalid 0 front of a binary number.
    public static int[] removeInvalidZero(int[] arr){

        int sumZero = 0; // Used to count the number of 0.
        int i = 0;
        int j = 0;

        // Read each consecutive 0 in front of the array and do statistics.
        while(arr[i] == 0){
            sumZero++;
            i++;
            if(checkBitArray.length -1 == arr.length - sumZero){
                break;
            }
        }

        int[] remainder = new int[arr.length - sumZero];
        while(i < arr.length){
            remainder[j] = arr[i];
            j++;
            i++;
        }

        System.out.println("remainder:");
        System.out.print(" ");
        for(int index : remainder){
            System.out.printf(" %d",index);
        }
        System.out.println("\nThe length of remainder:" + remainder.length);
        System.out.println();

        return remainder;

    }
    // Convert binary numbers to decimal numbers.
    public static long convertBinaryToDecimal(int[] arr){

        long sum = 0L;
        for(int i = 0; i < arr.length; i++){
            int temp = i;
            int mul = 1;

            while(temp < arr.length - 1){
                mul *= 2; // mul <<= 1;
                temp++;
            }

            sum += arr[i] * mul;

        }

        return sum;

    }

    // Check if the transmission is correct by verification.
    public static boolean checkTransmission(long sourceNum, long checkNum){

        return sourceNum % checkNum == 0;
    }
}

运行结果

原文地址:https://www.cnblogs.com/zwxo1/p/11824425.html

时间: 2024-10-08 13:03:21

计算机网络——CRC校验码的简单测试的相关文章

Redis源码中的CRC校验码(crc16、crc64)原理浅析

在阅读Redis源码的时候,看到了两个文件:crc16.c.crc64.c.下面我抛砖引玉,简析一下原理. CRC即循环冗余校验码,是信息系统中一种常见的检错码.大学课程中的"计算机网络"."计算机组成"等课程中都有提及.我们可能都了解它的数学原理,在试卷上手工计算一个CRC校验码,并不是难事.但是计算机不是人,现实世界中的数学原理需要转化为计算机算法才能实现目的.实际上作为计算机专业背景人并不会经常使用或接触到CRC的计算机算法实现的原理,通常是电子学科背景的人士

CRC校验码

下内容摘自笔者即将出版的最新著作<深入理解计算机网络>一书.本书将于12月底出版上市,敬请留意!! 本书原始目录参见此文:http://winda.blog.51cto.com/55153/1063878 5.3.2 循环冗余校验检错方案 上节介绍的奇偶校验码(PCC)只能校验一位错误,本节所要介绍的循环冗余校验码(CRC)的检错能力更强,可以检出多位错误. 1. CRC校验原理 CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的.其实很简单的问题,其根本

CRC校验码的verilog实现与仿真结果

循环冗余校验码(CRC)的基本原理是: 将被处理的报文比特序列当做一个二进制多项式A(x)的系数,(任意一个由二进制位串组成的代码都可以和一个系数仅为'0'和'1'取值的多项式一一对应.例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111),该系数乘以2^n(n为生成多项式g(x)中x的最高次幂)以后再除以发送方和接收方事先约定好的生成多项式g(x)后,求得的余数P(x)就是CRC校验码,把它副到原始的报文A(x)后面形成新的报

CRC校验码原理、实例、手动计算

CRC16实现代码 思路:取一个字符(8bit),逐位检查该字符,如果为1,crc^crc_mul;同时,如果原本crc最高位是1,那么crc^crc_mul后左移1位,否则只是左移一位.计算完一个字符后,装入下一个字符. #include<stdio.h> #define crc_mul 0x1021 //生成多项式 unsigned int cal_crc(unsigned char *ptr, unsigned char len) { unsigned char i; unsigned

Modbus协议 CRC 校验码

CRC(循环冗余校验)在线计算 http://www.ip33.com/crc.html 里面的8005的多项式值,但网上看到的算法都是用A001来异或的 ----------------------------------------------------- 0x8005=1000 0000 0000 0101B  0xA001=1010 0000 0000 0001B 对比两个二进制高低位正好是完全相反的,CRC校验分为正向校验与反向校验.正向校验高位在左,反向校验低位在左 正向校验使用左

[C语言]模拟人工计算CRC校验码

组成原理课程设计要实现CRC码的生成与校验,然而并不会用硬件实现... 只好先用C写着玩玩,做题还能用上...网原要考的... 例题:要发送的数据为1101011011,CRC生成多项式P(X)=X4+X+1,求应添加在数据后面的余数. 笔算过程: 编程算: 附上小白的代码... 1 #include "stdafx.h" 2 #define DATABIT_LENGTH 10 //数据位数 3 #define GENERATOR_LENGTH 5 //生成多项式位数 4 #defin

常用校验码(奇偶校验,海明校验,CRC)学习总结

常用校验码(奇偶校验,海明校验,CRC)学习总结 一.为什么要有校验码? 因为在数据存取和传送的过程中,由于元器件或者噪音的干扰等原因会出现错误,这个时候我们就需要采取相应的措施,发现并纠正错误,对于错误的检测和校正,大多采取"冗余校验"的思想,即除原数据外,额外增加若干位编码,这些新增的代码称为校验位. 二.数据是如何校验的? 输入的数据m经过f得到p校验位. 数据m和校验位一起通过存储器或传输线路,分别得到m'和p',这两者可能和m,f相同,也可能由于传输储存发生问题而不同. 由数

[技术栈]CRC校验原理及C#代码实现CRC16、CRC32计算FCS校验码

1.CRC.FCS是什么 CRC,全称Cyclic Redundancy Check,中文名称为循环冗余校验,是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误.它是利用除法及余数的原理来作错误侦测的. FCS,全称Frame Check Sequence,中文名称为帧校验序列,俗称帧尾,即计算机网络数据链路层的协议数据单元(帧)的尾部字段,是一段4个字节的循环冗余校验码. 注:CRC循环冗余校验和FCS帧校验序列是

CRC校验程序1:CRC循环冗余校验码计算

CRC全称Cyclic Redundancy Check,中文称为循环冗余检查.它是一种数据传输检错的机制,能够对数据进行多项式计算,并将得到的结果与接收设备共享,保证数据传输的正确性和完整性. 算法流程如下: 1. Load a 16-bit register with FFFF hex (all ‘1’s). Call this the CRC register. 2. Exclusive OR the first 8-bit byte of the message with the low