我正在尝试提供C / C ++函数来计算给定十六进制值数组的校验和。
char * hex =“ 3133455D332015550F23315D”;
例如,上述缓冲区有12个字节,然后最后一个字节是校验和。
现在需要做的是,将1st 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;
答案 0 :(得分:2)
使用加法来获取校验和至少是很奇怪的。通用校验和使用按位异或或完整crc。但是假设它确实是您所需要的,则可以通过iex(1)> xs = [1, 2, 3]
[1, 2, 3]
iex(2)> ys = [3, 4, 5]
[3, 4, 5]
iex(3)> Enum.any?(xs, fn x -> x in ys end)
true
操作轻松完成:
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;
}
上进行操作时,超过字节值的所有内容都会被正确丢弃,并获得您的值(示例中为26)。