计算校验和的逐位运算符

Bitwise operator to calculate checksum

本文关键字:运算符 和的 校验 校验和 计算      更新时间:2023-10-16

Am试图想出一个C/C++函数来计算给定十六进制值数组的校验和。

char*hex="3133455D332015550F23315D";

例如,上述缓冲器具有12个字节,然后最后一个字节是校验和。

现在需要做的是,将前11个单独的字节转换为十进制,然后求和。

即31=49,33=51,。。。。。

所以49+51+。。。。。。。。。。。。。。。。。。。。。

然后将这个十进制值转换为十六进制。然后取该十六进制值的LSB并将其转换为二进制。

现在取这个二进制值的2的补码,并将其转换为十六进制。在此步骤中,十六进制值应等于第12个字节。

但是上面的缓冲区只是一个例子,所以它可能不正确。

因此,这涉及到多个步骤。

我正在寻找一种简单的方法来使用逐位运算符实现这一点。

我做了这样的事情,但它似乎占用了前2个字节,没有给我正确的答案。

int checksum (char * buffer, int size){
int value = 0;
unsigned short tempChecksum = 0;
int checkSum = 0;
for (int index = 0; index < size - 1; index++) {
value = (buffer[index] << 8) | (buffer[index]);
tempChecksum += (unsigned short) (value & 0xFFFF);
}
checkSum = (~(tempChecksum & 0xFFFF) + 1) & 0xFFFF;  
}

我无法让这个逻辑发挥作用。我没有足够的嵌入式编程来理解逐位运算符。欢迎任何帮助。

答案

我通过以下更改完成了此操作。

for (int index = 0; index < size - 1; index++) {
value = buffer[index];
tempChecksum += (unsigned short) (value & 0xFFFF);
}
checkSum = (~(tempChecksum & 0xFF) + 1) & 0xFF;

使用加法来获得校验和至少很奇怪。常见的校验和使用按位xor或全crc。但假设它确实是您所需要的,则可以使用unsigned char操作轻松完成:

#include <stdio.h>
char checksum(const char *hex, int n) {
unsigned char ck = 0;
for (int i=0; i<n; i+=1) {
unsigned val;
int cr = sscanf(hex + 2 * i, "%2x", &val);   // convert 2 hexa chars to a byte value
if (cr == 1) ck += val;
}
return ck;
}
int main() {
char hex[] = "3133455D332015550F23315D";
char ck = checksum(hex, 11);
printf("%2x", (unsigned) (unsigned char) ck);
return 0;
}

当在unsigned char上进行操作时,所有超过字节值的东西都会被正确地丢弃,从而获得您的值(示例中为26(。