由于在项目中,经常会碰到一些十六进制传输的字符串,今天看文档,看了一个不错的校验算法,来分享一下:
传输包的命令格式如下:
CMD - NBF - [data_byte0... data_byten] - CKS
where:
CMD - 命令字节,范围: 80h - FFh
NBF- 命令字节数,从data_byte0... data_byten 到CKS校验位的字节数
data_byte0... data_byten- 数据字节 从0 到n
CKS - 校验位
校验算法依据如下:
校验码计算公式:
CKSUM = (not (CMD + NBF + [data byte0] + ... [data byten] ) + 1) & 7Fh
根据规律,我们可以得出如下的推导,也就可以以此公式来作为验证的公式:
( ( CMD + NBF + [data byte1] + ... [data byten]) & 7Fh) + CKSUM) & 7Fh = 0
例子:
Example:
假如命令为:CAh 02h 00h CHKSUM
CHKSUM = not (CAh + 02h+ 00h)
= not (CCh)
= 34h
因此, 完整的命令是: CAh 02h 00h 34h
下面是相关的C语言校验码计算代码:
enum Boolean {FALSE, TRUE};
void AddChecksum(short num, char buf[])
{
char checksum;
short i;
checksum = 0;
for (i = 0; i < num; i++)
checksum = (char) (checksum + buf[i]);
checksum = (char) ((-checksum) & 0x7F);
buf[num] = checksum;
}
下面是相关的C语言包验证的代码:
Boolean IsChecksumValid(char *lpBuf, short num)
{
char checksum;
checksum = *lpBuf;
lpBuf++;
num--;
for (; num > 0; num--) {
if (*lpBuf >= 0x80)
return FALSE; // invalid data byte
checksum = (char) (checksum + *lpBuf);
lpBuf++;
}
checksum &= 0x7F;
if (checksum == 0)
return TRUE;
else return FALSE; // invalid checksum
}