计算校验和的逐位运算符
Bitwise operator to calculate checksum
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(。
相关文章:
- 构造函数和转换运算符之间的重载解析
- 为什么同时覆盖全局新运算符和特定于类的运算符不是模棱两可的行为?
- 仅具有运算符()的结构和普通函数之间的实际区别
- C++ 中的按位运算符和重载
- 运算符 new 的执行顺序和构造函数的参数
- C++ 20 中的运算符 == 和 <=> 应该作为成员还是自由函数实现?
- 你能帮我了解重载一元运算符和二进制运算符之间的区别吗?
- 矩阵模板类中的重载运算符 *= 和运算符 +
- 为什么我的类工作正常,即使在返回垃圾值作为赋值运算符和空复制构造函数的返回之后
- 赋值运算符之间的差(+=和=)
- 计算校验和的逐位运算符
- 运算符[]和运算符int()的不明确重载
- 为什么这个涉及重载运算符和隐式转换的C++表达式是不明确的
- 如何翻译这个给定代码中的 ::* 运算符和member_fn?
- 用于测量重载运算符和成员函数的时间的函数
- C++:比较运算符>和字符串文本的意外结果
- C 和 C++ 中运算符大小的不同输出
- 创建指针是否超过非数组指针的末尾,而不是从 C++17 中的一元运算符和未定义的行为派生?
- llvm::Module 是运算符 .* 和 ->* 的左侧
- 关于运算符 -> 和 () 的求值顺序