这段代码如何验证校验和?
How does this piece of code verify a checksum?
上下文:
我的老师将 Darwin-OP 框架从 C++ 移植到 Java,让像我这样的学生无需掌握 C++ 即可使用它。 Darwin 有两个控制器:主控制器运行 Linux 和运行 java 代码,并与控制所有 sensors/servo's/transducers等
Darwin 使用 motion.bin 文件,其中存储了 256 页的列表。每页为 512(8 * 64)字节,由 7 个步骤(每个 64 字节)加上一个页头(也是 64 字节)组成。每个步骤都包含伺服器要采取的位置(0-4095 之间的值)。因此,为了让达尔文移动他的手臂,他经历了 (<7) 步,直到完成最后一步。
页眉内有一个 1 字节的校验和。 Java代码中包含了两种计算和验证校验和的方法:
private static boolean VerifyChecksum(PAGE page) {
byte checksum = (byte)0x00;
byte[] pagebytes = page.GetBytes();
for (int i = 0; i < pagebytes.length; i++) {
checksum += pagebytes[i];
}
if (checksum != (byte)0xFF) {
return false;
}
return true;
}
private static void SetChecksum(PAGE page) {
byte checksum = (byte)0x00;
byte[] pagebytes = page.GetBytes();
page.header.checksum = (byte)0x00;
for (int i = 0; i < pagebytes.length; i++) {
checksum += pagebytes[i];
}
page.header.checksum = (byte)((byte)0xFF - checksum);
}
主要问题:谁能解释一下校验和是如何验证的?我不明白为什么它会检查 checksum != (byte)0xFF
。为什么不直接比较计算出的 checksum
和 page.header.checksum
?
额外问题: 为什么首先检查文件完整性? .bin 文件中的页面损坏是否很常见?
要计算校验和,请对文件中的所有字节执行异或运算,然后 return 0xFF 减去该值。
传入校验和方法的文件是校验和位置为0x00的最终文件。
sum = 0xFF - XOR(file)
对于二进制,加法与 XOR 相同,因此行 checksum += pagebytes[i];
你教授的验证方法,将异或整个文件。也就是说,校验和方法的原始参数,以及作为校验和方法输出的附加字节。
所以预期的结果是:
XOR(file, sum)
= XOR(file) + sum
= XOR(file) + 0xFF - XOR(file)
= 0xFF
假设页眉是页面的一部分。然后计算所有字节 x 的总和并将 255-x 存储为校验和。验证时,计算y + 255 - x 必须等于255。如果是,则x 和y 是相同的数。
请注意,所有计算都是以 256 为模执行的,因此 x 和 y 始终在 0 到 255 的范围内。
上下文: 我的老师将 Darwin-OP 框架从 C++ 移植到 Java,让像我这样的学生无需掌握 C++ 即可使用它。 Darwin 有两个控制器:主控制器运行 Linux 和运行 java 代码,并与控制所有 sensors/servo's/transducers等
Darwin 使用 motion.bin 文件,其中存储了 256 页的列表。每页为 512(8 * 64)字节,由 7 个步骤(每个 64 字节)加上一个页头(也是 64 字节)组成。每个步骤都包含伺服器要采取的位置(0-4095 之间的值)。因此,为了让达尔文移动他的手臂,他经历了 (<7) 步,直到完成最后一步。
页眉内有一个 1 字节的校验和。 Java代码中包含了两种计算和验证校验和的方法:
private static boolean VerifyChecksum(PAGE page) {
byte checksum = (byte)0x00;
byte[] pagebytes = page.GetBytes();
for (int i = 0; i < pagebytes.length; i++) {
checksum += pagebytes[i];
}
if (checksum != (byte)0xFF) {
return false;
}
return true;
}
private static void SetChecksum(PAGE page) {
byte checksum = (byte)0x00;
byte[] pagebytes = page.GetBytes();
page.header.checksum = (byte)0x00;
for (int i = 0; i < pagebytes.length; i++) {
checksum += pagebytes[i];
}
page.header.checksum = (byte)((byte)0xFF - checksum);
}
主要问题:谁能解释一下校验和是如何验证的?我不明白为什么它会检查 checksum != (byte)0xFF
。为什么不直接比较计算出的 checksum
和 page.header.checksum
?
额外问题: 为什么首先检查文件完整性? .bin 文件中的页面损坏是否很常见?
要计算校验和,请对文件中的所有字节执行异或运算,然后 return 0xFF 减去该值。
传入校验和方法的文件是校验和位置为0x00的最终文件。
sum = 0xFF - XOR(file)
对于二进制,加法与 XOR 相同,因此行 checksum += pagebytes[i];
你教授的验证方法,将异或整个文件。也就是说,校验和方法的原始参数,以及作为校验和方法输出的附加字节。
所以预期的结果是:
XOR(file, sum)
= XOR(file) + sum
= XOR(file) + 0xFF - XOR(file)
= 0xFF
假设页眉是页面的一部分。然后计算所有字节 x 的总和并将 255-x 存储为校验和。验证时,计算y + 255 - x 必须等于255。如果是,则x 和y 是相同的数。
请注意,所有计算都是以 256 为模执行的,因此 x 和 y 始终在 0 到 255 的范围内。