安全文件覆盖工具的核心目标是让被删除的文件无法通过数据恢复手段还原,普通删除操作仅会移除文件系统的索引记录,实际存储的数据块仍保留在磁盘中,而多次随机数覆写算法会反复向文件对应的存储区域写入随机数据,覆盖原有内容,从物理层面破坏原有数据的可读性。

实现核心思路
整个工具的实现流程可以分为三个核心步骤:首先定位需要擦除的目标文件,确认文件存在且具备写入权限;然后按照预设的覆写次数,每次生成对应文件大小的随机数据,写入到文件的每一个字节位置;最后完成覆写后删除文件索引,确保数据无法被恢复。
随机数生成方案
为了保证覆写数据的随机性,需要选择可靠的随机数生成方式,C++中可以使用<random>库提供的随机数引擎,避免使用rand()这类伪随机性较差的函数。生成随机字节时,需要覆盖0到255的所有可能取值,确保原有数据被完全打乱。
覆写次数选择
常见的覆写次数有1次、3次、7次等,次数越多安全性越高,但耗时也会相应增加。一般场景下3次覆写已经可以满足大部分安全需求,对安全性要求极高的场景可以选择7次或更多次覆写。
完整代码实现
以下是基于C++17标准实现的完整安全文件覆盖工具代码,支持自定义覆写次数,包含必要的异常处理逻辑:
#include <iostream>
#include <fstream>
#include <random>
#include <filesystem>
#include <vector>
#include <cstdint>
// 安全文件覆盖函数,filePath为文件路径,overwriteTimes为覆写次数,默认3次
bool wipeFile(const std::string& filePath, int overwriteTimes = 3) {
// 检查文件是否存在
if (!std::filesystem::exists(filePath)) {
std::cerr << "目标文件不存在: " << filePath << std::endl;
return false;
}
// 检查是否为普通文件
if (!std::filesystem::is_regular_file(filePath)) {
std::cerr << "目标不是普通文件,无法执行覆写操作" << std::endl;
return false;
}
// 获取文件大小
uintmax_t fileSize = std::filesystem::file_size(filePath);
if (fileSize == 0) {
std::cerr << "文件大小为0,无需覆写" << std::endl;
return true;
}
// 初始化随机数生成器
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<uint8_t> dis(0, 255);
// 打开文件用于二进制写入
std::fstream file(filePath, std::ios::binary | std::ios::in | std::ios::out);
if (!file.is_open()) {
std::cerr << "无法打开文件: " << filePath << std::endl;
return false;
}
// 执行多次覆写
for (int i = 0; i < overwriteTimes; ++i) {
// 移动文件指针到开头
file.seekp(0);
// 逐字节写入随机数据
for (uintmax_t j = 0; j < fileSize; ++j) {
uint8_t randomByte = dis(gen);
file.write(reinterpret_cast<const char*>(&randomByte), sizeof(randomByte));
if (!file.good()) {
std::cerr << "第" << i + 1 << "次覆写失败,位置: " << j << std::endl;
file.close();
return false;
}
}
file.flush();
std::cout << "完成第" << i + 1 << "次随机覆写" << std::endl;
}
// 关闭文件
file.close();
// 删除文件索引
try {
std::filesystem::remove(filePath);
std::cout << "文件已彻底删除" << std::endl;
} catch (const std::filesystem::filesystem_error& e) {
std::cerr << "删除文件失败: " << e.what() << std::endl;
return false;
}
return true;
}
int main() {
std::string targetFile;
int times;
std::cout << "请输入需要安全擦除的文件路径: ";
std::cin >> targetFile;
std::cout << "请输入覆写次数(默认3次,直接回车使用默认值): ";
std::cin >> times;
// 如果用户没有输入次数,使用默认值3
if (std::cin.fail()) {
times = 3;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}
if (times <= 0) {
std::cerr << "覆写次数必须大于0" << std::endl;
return 1;
}
bool result = wipeFile(targetFile, times);
if (result) {
std::cout << "文件安全擦除完成" << std::endl;
} else {
std::cout << "文件安全擦除失败" << std::endl;
}
return 0;
}
代码说明与注意事项
上述代码使用了<filesystem>库处理文件路径相关操作,编译时需要开启C++17及以上标准,比如使用g++编译时需要添加-std=c++17参数。随机数生成部分使用std::random_device获取真随机种子,配合std::mt19937引擎生成分布均匀的随机字节,避免伪随机导致覆写数据有规律。
需要注意的是,该工具仅适用于普通机械硬盘和常规固态硬盘的文件擦除,部分企业级固态硬盘带有自带的加密擦除功能,使用硬件层面的擦除效率会更高。另外如果文件被其他进程占用,会导致文件无法打开,需要在执行工具前确保目标文件没有被其他程序使用。
扩展优化方向
- 可以增加覆写模式选择,除了随机数据覆写,还可以支持全0、全1、特定模式数据覆写,满足不同场景的安全需求
- 添加进度显示功能,对于大文件覆写时可以让用户了解当前执行进度
- 支持批量文件擦除,允许用户输入目录路径,自动遍历目录下所有文件执行安全擦除操作
- 增加权限检查逻辑,提前判断当前用户是否有目标文件的读写和删除权限,避免执行到一半才报错