如何检查大二进制文件是否连续包含小文件?求代码修复方案
看起来你的朴素字符串匹配逻辑存在几个可能导致误判的问题,我来帮你分析并修复:
可能的误判原因
- 有符号字符的比较问题:二进制文件中包含0x80到0xFF的字节时,用
signed char存储会被解析为负数,和病毒签名中的字节(如果是无符号读取的)比较时可能出现错误的相等判断,反之亦然,导致错误匹配。 - 内存越界访问:原循环条件是
i < len,当i接近len时,即使剩下的字符数不足virusLen,循环仍会继续,可能访问到currentFileString数组之外的内存区域。如果这些越界内存的内容刚好和病毒签名的剩余部分匹配,就会误判为true。 - 匹配逻辑的回溯混淆:原代码中部分匹配失败后直接重置
counter为0,虽然逻辑本身没问题,但结合越界问题时更容易触发误判,且代码可读性较差。
修复后的代码
#include <stdbool.h> bool checkIfInfected(const unsigned char* virusSignature, const unsigned char* currentFileString, size_t fileLen, size_t virusLen) { // 边界条件处理:签名为空或文件比签名短,直接返回false if (virusLen == 0 || fileLen < virusLen) { return false; } // 优化循环范围:只遍历到有足够字符匹配签名的位置 for (size_t i = 0; i <= fileLen - virusLen; i++) { size_t matchCount = 0; // 检查从当前位置开始的连续字节是否完全匹配签名 while (matchCount < virusLen && currentFileString[i + matchCount] == virusSignature[matchCount]) { matchCount++; } if (matchCount == virusLen) { return true; } } return false; }
关键修复点说明
- 改用无符号字符:将
char替换为unsigned char,确保二进制字节的比较基于原始0-255的数值范围,彻底避免有符号扩展带来的错误比较。 - 添加边界检查:提前过滤掉不可能匹配的情况(签名为空、文件过短),减少无效计算。
- 优化循环范围:将循环上限设为
fileLen - virusLen,保证每个起始位置后都有足够字符完成匹配,既提升效率,又彻底杜绝越界访问的风险。 - 简化匹配逻辑:对每个起始位置单独检查后续字节,逻辑更清晰,也避免了原代码中
counter状态残留导致的潜在问题。
额外建议
读取文件时一定要用二进制模式(比如C语言中用"rb"打开),避免文本模式下的换行符转换等操作修改文件原始二进制内容;同时要确保传递的fileLen和virusLen是文件的实际字节数,不要传递数组的总容量(如果数组有预留空间的话)。
内容的提问来源于stack exchange,提问作者alon nahmias
相关产品推荐
相关产品推荐

