文章目录
- 一、BCC校验介绍
- 二、工作原理
- 三、BCC校验的优缺点
- 四、适用场景
- 五、示例
一、BCC校验介绍
BCC (Block Check Character)是一种数据校验方法,通常用于检测和校验数据传输中的错误。其核心是将一个数据块里的所有字节按位异或(XOR),从而生成一个检验字符。若这个检验字符与实际计算得到的不符,就表示数据传输中可能发生了错误。因检验字符是将所有字节异或得出,故也称为异或校验。
什么是异或运算?异或运算(XOR)是一种基本的逻辑运算,它对二进制位进行操作。其基本规则是如果两个二进制位不同,结果为1。如果两个二进制位相同,结果为0,简单总结:同为0,异为1。
以下是真值表,该表展示了所有可能的输入(A和B)以及相对应的输出(A XOR B):
A | B | A XOR B |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
例如00001010和00001100进行异或运算
二、工作原理
数据分块:
待传输的数据被分成多个块,每个块由若干个字节组成。
按位异或计算:
对该数据块中所有字节进行按位异或运算,得到一个校验字节。将计算得到的校验字节附加到该数据块的末尾。
数据传输:
将附加有校验字节的数据块进行传输。
数据校验:
在接收端,对接收到的数据块重新进行按位异或运算,得到一个校验字节。比较接收到的校验字节和计算得到的校验字节。如果相等,则说明该数据块在传输过程中没有发生错误;否则,就表示可能存在传输错误。
三、BCC校验的优缺点
BCC校验 (异或校验) 作为一种简单且高效的错误检测方法,有着自身的优缺点,适用于不同的应用场景。以下是对异或校验的详细优缺点分析:
优点
计算简单高效: 异或运算是最基本的逻辑操作之一,计算速度非常快,并且在硬件上也能高效实现。特别适用于需要高效实时校验的场景。
实现成本低: 由于异或运算的简单性,使用它进行校验的实现成本非常低,适合资源受限的环境,如嵌入式系统。
单比特错误检测: 异或校验能够检测单比特错误,即数据传输或存储过程中由于某个比特的翻转导致的错误。
轻量级: 相对于复杂的校验方式,如循环冗余校验(CRC)和哈希校验,异或校验所需的额外存储空间和计算资源非常少。因此,非常适合对资源占用有严格要求的应用场景。
缺点
有限的错误检测能力: 异或校验只能可靠地检测单比特错误和奇数位数的比特错误,但对于多个比特同时出现错误(即多比特错误),尤其是偶数位的比特错误,异或校验可能无法检测到。例如:假设有两个字节A = 11001100和B = 10101010,无论哪两个位置同时发生错误,异或结果可能保持不变,导致无法检测到错误。
无法定位错误: 异或校验只能检测到是否发生错误,但无法确定错误的具体位置。因此,虽然能发现数据损坏,但无法直接纠正错误。
不适用于高可靠性要求的场景: 对于数据可靠性要求非常高的场合,如金融数据传输、关键性医疗设备数据等,异或校验的检测能力不足,通常需要更复杂的校验算法,如CRC(循环冗余校验),哈希函数或甚至更高级的数据完整性保护机制。
四、适用场景
鉴于其优缺点,异或校验适用于以下场景:
资源受限的嵌入式系统:嵌入式系统中资源有限,使用复杂的校验算法可能带来额外的计算负担,异或校验则因其简洁性成为一种理想选择。
实时数据流传输:在实时传输中,快速、低延迟的校验方法可以减少传输延迟。
非关键数据传输:在数据错误可容忍范围内,使用异或校验可以达到良好的效果,并且不会带来过多的计算资源消耗。适用于大多数要求不高的数据通讯,例如IC卡接口通讯,很多基于串口的通讯都用这种既简单又相当准确的方法。
五、示例
main.c源码
#include <stdio.h>/*** funBccCreate: 异或校验,计算校验码* @p[IN]: 字符串指针* @len[IN]: 字符串长度* @bcc[OUT]: bcc校验码* return: 0 成功 , -1 失败*/
int funBccCreate(unsigned char *p, unsigned int len, unsigned char *bcc)
{ if((NULL == p) || (0 == len) || (NULL == bcc)){return -1;}*bcc = 0;for(; len > 0; len--){*bcc^=*p++;}return 0;
}int main(int argc, char *argv[])
{unsigned char checksum = 0;unsigned char data[] = {0x12, 0x34, 0x56, 0x78, 0x90};unsigned int length = sizeof(data) / sizeof(data[0]);int ret = funBccCreate(data, length, &checksum);if(0 == ret){printf("Computed BCC Checksum: 0x%02X\n", checksum);}else{perror("funBccCreate err :");}return 0;
}
编译运行结果:
通过网页在线计算校验码对比结果: