按位运算符计算校验和

时间:2018-07-24 11:22:56

标签: c++ c

我正在尝试提供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;

1 个答案:

答案 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)。