如何计算modbus-rtu的crc校验码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何计算modbus-rtu的crc校验码相关的知识,希望对你有一定的参考价值。

给你个C#语言的CRC16类,自己编程可以用这个,很简单。或者下载一个CRC16校验码生成器。
public class CRC16Class

public UInt16 Crc16(byte[] Data, int StartByte, int Length)

try

UInt16 CRC = 0xFFFF, temp = 0xA001;
for (int k = StartByte; k < StartByte + Length; k++)

CRC ^= Data[k];
for (int i = 0; i < 8; i++)

int j = CRC & 1;
CRC >>= 1;
CRC &= 0x7FFF;
if (j == 1)
CRC ^= temp;


return CRC;

catch (Exception ex)


return 0;

参考技术A 百度文库里有文字章

可以查看

计算机网络——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 : 
 G(x) = x^5 + x^3 + x^0 , 
 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("
Note that you can only enter 0 1.
Please 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("
sum1 :" + 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("
sum2 :" + 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"--->
", 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("
The %d XOR operation or modulo 2 operation:
", counts);
        counts++;
        System.out.printf(" ");
        for(int index1 : arr1){
            System.out.printf(" %d", index1);
        }
        
        System.out.print("
^");
        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("
After modulo 2 operation arr1:");
        System.out.printf("
___________________________________________
");
        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("
The 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;
    }
}

运行结果

技术图片

技术图片

技术图片

技术图片

技术图片

以上是关于如何计算modbus-rtu的crc校验码的主要内容,如果未能解决你的问题,请参考以下文章

crc校验码计算方法是啥?

如何简单的计算且通俗的理解CRC码(循环冗余校验码)含过程推演详细步骤

如何简单的计算且通俗的理解CRC码(循环冗余校验码)含过程推演详细步骤

MODBUS通讯CRC校验码怎么算,有那位能告诉我呀

工控常用LRC XOR累加和CRC校验工具校验码自动生成软件多计算方式

CRC校验码