比特串校验和计算问题:结果与预期仅差一位求解
问题分析
你的代码计算前三个字节的和为0x37(二进制00110111),与0xF0按位或后得到0xF7(11110111),和预期的0xF6仅最后一位不同,以下是几种符合逻辑的修正方案:
解决方法
1. 按「原字节取反后求和」逻辑修正
如果校验和的计算规则是先对每个输入字节取反,求和后取低8位,再与0xF0按位或,修改checksum函数即可:
def checksum(bytes): # 对每个字节取反后求和,保留低8位 return (sum(0xFF ^ b for b in bytes) & 0xFF)
此时计算结果为0xC6,与0xF0按位或后得到0xF6,完全匹配预期校验和。
2. 增加奇偶校验位调整
如果协议要求整个数据(含校验和)的1的个数为偶数:
- 前三个字节的1总数:
01010000(2个) +10000000(1个) +01100111(5个) = 8个(偶数) - 当前得到的
0xF7有7个1,总数为15(奇数),需翻转最后一位变为偶数个1
在原代码中添加奇偶校验调整:
checksum_bytes = checksum_bytes | 0xf0 # 计算当前校验和的1的个数 checksum_ones = bin(checksum_bytes).count('1') # 若总1的个数为奇数,翻转最后一位 if (8 + checksum_ones) % 2 != 0: checksum_bytes ^= 0x01 checksum_bytes = bin(checksum_bytes)
执行后会将0xF7调整为0xF6,符合预期。
3. 直接修正末位(快速匹配)
如果仅需临时匹配预期结果,可直接对求和结果的末位取反后再与0xF0按位或:
checksum_bytes = (checksum_bytes ^ 0x01) | 0xf0
此方法简单直接,但需确认协议是否确实存在该规则。
内容的提问来源于stack exchange,提问作者Swordfish II
相关产品推荐
相关产品推荐

