我实现了这个我发现的校验和算法,它工作正常,但我无法弄清楚这个"& = 0xFF"线实际上在做。
我向上看了一下&运算符,并且维基百科声称它是A与B中所有位的逻辑AND。我还读到0xFF相当于255 - 这应该意味着所有位都是1.如果你取任何数字& 0xFF,不是这个号码的标识吗?所以A& 0xFF产生A,对吗?
然后我想,等一下,下面代码中的校验和是32位Int,但0xFF是8bit。这是否意味着校验和& = 0xFF的结果是24位最终为零并且只保留剩余的8位?在这种情况下,校验和被截断为8位。这就是这里发生的事情吗?
private int CalculateChecksum(byte[] dataToCalculate)
{
int checksum = 0;
for(int i = 0; i < dataToCalculate.Length; i++)
{
checksum += dataToCalculate[i];
}
//What does this line actually do?
checksum &= 0xff;
return checksum;
}
另外,如果结果被截断为8位,那是因为32位在校验和中是没有意义的吗?是否有可能出现这样一种情况:当8位校验和不能时,32位校验和会捕获损坏的数据?
答案 0 :(得分:8)
它屏蔽了较高的字节,只留下较低的字节。
checksum &= 0xFF;
语法上的简称:
checksum = checksum & 0xFF;
其中,由于它正在进行整数运算,0xFF
会扩展为int
:
checksum = checksum & 0x000000FF;
哪个屏蔽了高3字节并将低字节作为整数(不是字节)返回。
回答你的另一个问题:由于32位校验和比8位校验和宽得多,它可以捕获8位校验和不会发生的错误,但是双方都需要使用相同的校验和计算上班。
答案 1 :(得分:5)
好像你对情况有了很好的了解。
这是否意味着校验和&amp; = 0xFF的结果是24位最终为零并且只保留剩余的8位?
是
是否有可能出现这样一种情况:当8位校验和没有时,32位校验和会捕获损坏的数据?
是
答案 2 :(得分:3)
这通过添加它们并忽略任何溢出到更高位的位来对字节(8位值)执行简单的校验和。你怀疑,最后的&amp; = 0xFF只是将值截断为32位的8LSB(如果这是你的编译器的int定义)值,导致0到255之间的无符号值。
截断到8位并丢弃高阶位只是为此校验和实现定义的算法。从历史上看,这种检查值用于提供一些信任,即通过简单的串行接口正确传输了一个字节块。
要回答您的上一个问题,然后是,32位检查值将能够检测到8位检查值无法检测到的错误。
答案 3 :(得分:3)
是的,校验和被截断为8位
class Test {
@observable flag = true;
}
// is the same as:
class Test {
@observable flag;
constructor() {
this.flag = true;
}
}
保留最低8位,并将所有高位设置为0.
将校验和缩小到8位确实会降低可靠性。想想两个不同但最低8位相同的32位校验和。在截断到8位的情况下,两者都是相等的,在32位情况下它们不是。