c++怎么实现大文件的哈希校验_分块计算SHA256算法【附代码】

张开发
2026/4/21 3:40:29 15 分钟阅读
c++怎么实现大文件的哈希校验_分块计算SHA256算法【附代码】
不能直接读整个大文件进内存算SHA256因易OOM应分块如64KB用EVP_DigestUpdate增量计算注意二进制模式、gcount()判末块、EVP_DigestFinal_ex收尾及显式EVP_MD_CTX_free。为什么不能直接读整个大文件进内存算 SHA256因为会 OOM——哪怕只是 4GB 的文件在 32 位环境或内存受限容器里std::ifstream::read 一次性读取就可能失败64 位下虽不崩但占满几百 MB 内存毫无必要还拖慢其他 IO。SHA256 本身支持增量更新EVP_DigestUpdate 或 std::hasher::update分块才是正解。常见错误现象std::bad_alloc、程序卡死、校验结果和 sha256sum 不一致通常是因为没处理末尾不足块的边界。块大小建议选 6553664KB太小如 1KB系统调用开销大太大如 1MB对缓存不友好且在低内存设备上仍可能出问题必须用二进制模式打开文件std::ios::binary否则 Windows 下换行符会被悄悄转换哈希值必然错每次 read() 后要检查 gcount()不能只看 eof()——文件末尾读不满一块时gcount() 才是真实字节数OpenSSL 的 EVP 接口怎么安全分块更新别碰 SHA256_Init/SHA256_Update 这类底层 C 接口它们不校验指针/长度容易传错参数导致段错误或哈希错。用 EVP_MD_CTX EVP_DigestInit_ex 是 OpenSSL 官方推荐路径支持多线程安全重用上下文。实操要点立即学习“C免费学习笔记深入”初始化必须指定算法和 engineEVP_DigestInit_ex(ctx, EVP_sha256(), nullptr)漏掉 nullptr 可能触发未定义行为EVP_DigestUpdate 第二个参数是 const void*传 buffer.data() 没问题但确保 buffer 生命周期覆盖整个 update 过程最后一定要调 EVP_DigestFinal_ex不能只靠 EVP_DigestUpdate——否则摘要没完成输出全是 0错误检查不能省EVP_DigestInit_ex 和 EVP_DigestFinal_ex 返回 1 才成功否则查 ERR_print_errors_fp(stderr)用 std::filesystem::file_size 避免重复 stat有人边读边调 std::filesystem::file_size(path)其实没必要——它本质就是一次 stat() 系统调用。在校验前调一次就够了还能提前判断文件是否为空或权限不足。 Cleanup.pictures 智能移除图片中的物体、文本、污迹、人物或任何不想要的东西

更多文章