在c++项目中,为了防止写入的本地文件被篡改,可以在生成文件时先计算内容的MD5值,并把该摘要作为固定长度的校验头写在文件最前面。后续读取文件时,先读出校验头,再对剩余内容计算MD5进行比对,不一致就说明文件已被修改。

实现思路
整体流程分为写文件和读文件两部分。写文件时先准备好业务数据,计算其MD5字符串,将32字符的摘要与数据拼接后写入。读文件时先读取前32字节作为期望摘要,再对后面内容算MD5并比较。
MD5算法选择
可以使用轻量的公开MD5实现,将头文件和源文件加入工程。下面示例用一个简单的md5.h提供的接口:std::string md5(const std::string&)。
写入文件并添加校验头
以下代码演示写文件时自动添加MD5校验头:
#include <iostream>
#include <fstream>
#include <string>
#include "md5.h"
// 将内容写入文件,并在头部添加32字符MD5校验头
bool write_file_with_md5(const std::string& path, const std::string& content) {
std::string digest = md5(content);
std::ofstream out(path, std::ios::binary);
if (!out) {
return false;
}
// 先写校验头
out.write(digest.data(), digest.size());
// 再写正文
out.write(content.data(), content.size());
out.close();
return true;
}
int main() {
std::string data = "user=admin;level=5;";
if (write_file_with_md5("config.dat", data)) {
std::cout << "文件已写入并附带MD5校验头" << std::endl;
}
return 0;
}
读取文件并验证完整性
读取时先取前32字节,再对余下内容算MD5,进行字符串比较:
#include <iostream>
#include <fstream>
#include <string>
#include "md5.h"
bool read_and_check(const std::string& path, std::string& out_content) {
std::ifstream in(path, std::ios::binary);
if (!in) {
return false;
}
// 读取校验头
char head[32];
in.read(head, 32);
std::string expect(head, 32);
// 读取剩余内容
std::string body((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
in.close();
std::string actual = md5(body);
if (expect != actual) {
std::cout << "文件可能被篡改" << std::endl;
return false;
}
out_content = body;
return true;
}
int main() {
std::string content;
if (read_and_check("config.dat", content)) {
std::cout << "校验通过:" << content << std::endl;
}
return 0;
}
注意事项
- MD5校验头长度固定为32字符,读取时不要多读或少读。
- 如果业务数据本身可能包含二进制,请用binary模式并保证读写一致。
- MD5不是加密算法,只能检测意外修改,不能防止刻意攻击重算摘要,重要场景可改用HMAC。
在文件头写入摘要的方式简单有效,适合大多数本地配置和日志防篡改需求。
小结
通过在c++写文件时自动添加MD5校验头,我们能用少量代码实现基础的篡改检测。实际项目中可将写和读封装成工具函数统一调用。