C - 读取二进制文件,验证校验和

标签 c binaryfiles checksum code-assist

在 C 语言中,读取二进制文件内容并验证校验和的正确方法是什么?

这是我正在处理的数据示例:

0A 01 17 D8 04 00 07 9A 1F 10 FF CF 7F FF FF FF
FF 7F 7F 7F FF 7F FF FF FF FF 7F 81 01 01 03 01
01 01 01 81 00 73 67 68 66 97 6C 76 64 64 6A 6B
6E 64 66 67 44 41 [17 7A]

and

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 44 41 [00 85]

The checksum (between square brackets) stores the sum of the previous 54 bytes as a 2-byte (big-endian) number.

This is what I've been using:

#include <stdio.h>
int main(int argc, char **argv)
{
    FILE *f = fopen(argv[1], "rb");

    unsigned char data[512];
    fread(data, 1, 512, f);

    int i;
    int sum = 0;
    for (i = 0; i < 54; i++)
    {
        sum += data[i];
    }

    if ((sum >> 8)   == data[54] &&
        (sum & 0xFF) == data[55])
    {
        printf("Checksum is valid.\n");
    }
    else
    {
        printf("Checksum is invalid.\n");
    }
    system("pause");
}

我使用了一个字符数组来存储字节,使用索引在循环中重新计算校验和。为了验证我使用了一些按位移位和屏蔽。有更好的解决方案吗?

谢谢!

最佳答案

你写的是合理的,但如果应该只有 56 个字节,那么尝试读取 512 个字节没有实际意义。此外,不要重复 512,而是在第二次出现时使用 sizeof(data)。您可以将代码打包为一个函数,并且可以在不匹配时打印出实际和预期的校验和。校验和算法不是很敏感,因此很容易漏掉一些错误,例如转置错误,但它也会捕获相当多的错误。


嗯……再看一遍……你写了:

if ((sum >> 8)   == data[54] &&
    (sum & 0xFF) == data[55])

因为 sum 是一个(有符号的)int,你应该这样写:

if ((sum >> 8) & 0xFF == data[54] &&
    (sum & 0xFF)      == data[55])

否则,您可能会溢出。可能不会只有 54 个字节的数据,但如果要校验和的数据足够长(肯定超过 256 个字节),您最终得到的总和可能会大于 65535,并且比较会在不应该的情况下失败。我假设 sizeof(int) == 4,而不是 sizeof(int) == 2

关于C - 读取二进制文件,验证校验和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10150716/

相关文章:

c - Visual C 多线程文件读取

c++ - 从文件中读取字符串并转换为 bitset<12>

c - 从 csv 读取数据时出现问题

c - 如何限制Linux内核中任务系统调用的时间

c - 指向数组的 typedef 的指针

c++ - 如何将二进制数据硬编码为字符串

r - 如何检查下载的 R 镜像以确保它在镜像过程中没有被篡改或损坏?

hadoop - Hadoop 中的校验和验证

c++ - 保持 .exe 时间戳不变

我可以获得套接字缓冲区剩余大小吗?