协议解析 · 2025-08-04

终于有人把校验说明白了

大家好!我是付工。

我们做上位机开发的时候,经常会听到【校验】这个词。

今天给大家分享关于【校验】的一些个人理解。

校验目的

首先我们思考一下,为什么会存在校验?

原文配图 1

我们都知道,计算机底层都是通过二进制的方式进行传输。

但是在实际传输过程中,比特流由于会受到各种干扰,可能会出现比特差错,这种我们称之为误码。误码会导致数据错误,错误的数据带来的影响是巨大的,因此通信务必要保证报文的正确性。

此外,如果报文没有传输完成,但是接收方认为传输完成了,会导致收到的报文是不完整的。针对以上两种情况,我们提出了【校验】这种方式。

校验的目的是为了保证报文的正确性和完整性。

校验一般会有两种形式,一种是底层的校验,比如串口的奇偶校验、以太网的校验和,另一种是应用层的校验,比如CRC校验、异或校验等。

底层校验

1、串口的奇偶校验

串口通信中,奇偶校验通过添加一位校验位来检测数据传输中的错误,确保1的个数为奇数或偶数。 奇偶校验是一种简单而常用的方法,它通过添加一位校验位来确保传输数据中1的个数为奇数或偶数。

原文配图 2
原文配图 3

2、以太网校验和

待检验报文从头开始,每16位进行一次加法计算,如果遇到进位,则将高于16字节的进位部分的值加到最低位上,这样最终计算出来的和进行一次反码运算,就是检验和。

举例说明:假设数据部分为0xBB 0x5E 0xFC 0xED,对其求校验和。

1、0xBB5E+0xFCED=0x1 B84B;

2、将1放到最低位,得到结果是0xB84C;

3、再进行反码,结果就是0x47B3。

应用层校验

很多情况,单靠底层校验并不能完全保证数据准确性,所以我们还会通过应用层报文校验进行二次校验。

常用的应用层校验有CRC校验、LRC校验、异或校验、累加和校验等。

以累加和校验为例,下面是累加和校验的说明:

原文配图 4

其实无论什么校验方式,它的本质就是一种算法。

对于上位机开发来说,就是两个方法,一个是计算校验的方法,代码如下:

    /// <summary>
    /// 计算8位累加和校验(原始算法)
    /// </summary>
    public static byte CalculateSumCheck(byte[] data)
    {
        if (data == null || data.Length == 0)
            throw new ArgumentException("输入数据不能为空");

        unchecked // 允许算术溢出
        {
            byte sum = 0;
            foreach (byte b in data) sum += b;
            return sum;
        }
    }

另一个是反校验的方法,代码如下:

    /// <summary>
    /// 验证数据包校验和是否有效
    /// </summary>
    public static bool ValidatePacket(byte[] packet)
    {
        if (packet == null || packet.Length < 2)
            throw new ArgumentException("数据包长度至少需要2字节");

        byte[] payload = packet[..^1]; // 取除最后字节外的所有数据
        byte expectedChecksum = CalculateSumCheck(payload);
        return packet[^1] == expectedChecksum;
    }
本文为原文文字快照,已收录 4 张技术配图;二维码与推广图未收录。
标签:#校验 #CRC