C语言读取二进制文件特定位验证按位或运算结果的实现咨询
实现方案
核心原理
文件IO的最小操作单位是字节(8位),没有直接读取单个位的系统API,你可以先把完整文件内容加载到字节缓冲区,再通过位运算提取任意偏移位置的位做校验即可。
具体实现步骤
- 读取整个二进制文件到unsigned char类型的内存缓冲区,同时统计文件的总字节数,计算得到总位数为
总字节数 * 8
- 读取整个二进制文件到unsigned char类型的内存缓冲区,同时统计文件的总字节数,计算得到总位数为
- 定义位提取宏,输入缓冲区和位偏移值,返回对应位置的0/1值
- 从偏移0开始,每次步进3位,依次提取当前偏移的第0、1、2位,校验前两位的按位或结果是否等于第三位
- 校验不通过时可以直接记录错误位置终止流程,全部通过则校验完成
参考代码(C语言)
#include <stdio.h> #include <stdlib.h> // 位提取宏:返回buf缓冲区第n位的值(0或1),位顺序为字节高位在前 #define GET_BIT(buf, n) ((buf[(n) / 8] >> (7 - (n) % 8)) & 1) // 适配你需求的数组传参校验函数 int check_bits(unsigned char arr[3]) { return (arr[0] | arr[1]) == arr[2]; } int main(int argc, char* argv[]) { if (argc != 2) { printf("用法:%s <二进制文件路径>\n", argv[0]); return 1; } // 读取文件到缓冲区 FILE* fp = fopen(argv[1], "rb"); if (!fp) { perror("文件打开失败"); return 1; } fseek(fp, 0, SEEK_END); long file_size = ftell(fp); fseek(fp, 0, SEEK_SET); unsigned char* buf = malloc(file_size); fread(buf, 1, file_size, fp); fclose(fp); long total_bits = file_size * 8; // 兜底校验总位数是否为3的整数倍 if (total_bits % 3 != 0) { printf("文件总位数不是3的整数倍\n"); free(buf); return 1; } // 遍历校验 int all_pass = 1; for (long offset = 0; offset < total_bits; offset += 3) { unsigned char arr[3] = { GET_BIT(buf, offset), GET_BIT(buf, offset + 1), GET_BIT(buf, offset + 2) }; if (!check_bits(arr)) { printf("校验失败,位置:第%ld位开始的3位,值:%d%d%d,预期第三位为%d\n", offset, arr[0], arr[1], arr[2], arr[0] | arr[1]); all_pass = 0; // 可根据需求选择break终止或继续遍历统计所有错误 } } if (all_pass) { printf("所有位校验通过\n"); } free(buf); return 0; }
说明
- 代码完全贴合你原本用数组存3个值再传参校验的设计思路,无需修改你的原有校验逻辑
- 如果你需要调整位的读取顺序(比如按字节低位在前读取),只需要修改
GET_BIT宏里的移位逻辑,把7 - (n)%8改成(n)%8即可适配对应场景
内容的提问来源于stack exchange,提问作者thatDude
相关产品推荐
相关产品推荐

