获取文件任意位置的md5值,校验两个文件是否同一个文件
解决问题:
在我们对文件做加密、解密、传输等操作后,我们想要知道生成的文件是否还是正常可以使用时,这时我们需要校验下解密或传输后的文件跟源文件是否一致。通常去根据文件大小或文件的md5值。通常如果文件非常大,计算整个文件的md5值一般非常耗时,这是可以去抽取文件中的部分去计算md5,本文暂时计算文件前1024字节,最后1024字节对文件进行对比。
node 版本
测试两个文件是否一致。
valicateFileIsSame('C://VMwareWorkstation16.0.zip','C://VMwareWorkstation16.01.zip').then(res=>{
console.log('文件是否一致:',res)
});
/**
*
* 获取文件指定位置的md5值
* @param {*} filepath 文件路径
* @param {int} offset 起始值
* @param {int} length 读取长度
* @return {String} md5
*/
function getFileMd5(filepath, offset, length) {
return new Promise(function(resolve, reject) {
const fs = require('fs');
const crypto = require('crypto');
const md5sum = crypto.createHash('md5');
if (!fs.existsSync(filepath)) {
reject(new Error('The File is not existed!!!'));
}
fs.open(filepath, 'r', function(err, fd) {
if (err) {
reject(err);
}
const buf = Buffer.alloc(length);
fs.readSync(fd, buf, 0, length, offset);
md5sum.update(buf);
const md5str = md5sum.digest('hex').toUpperCase();
resolve(md5str);
});
});
}
// 校验首位2k的md5判断文件是否是同一个
async function valicateFileIsSame(sourceFilePath, tempFilePath) {
// 首先验证文件大小是否一致
const fs = require('fs');
let flag = false;
if (fs.existsSync(tempFilePath) && fs.existsSync(sourceFilePath)) {
// 源文件大小
const sourceFileStat = fs.statSync(sourceFilePath);
const sourceFileSize = sourceFileStat.size;
// 临时文件大小
const tempFileStat = fs.statSync(tempFilePath);
const tempFileSize = tempFileStat.size;
if (sourceFileSize == tempFileSize) { // 文件大小都一致,文件没问题概率已经很大了,下面md5校验不知是否还有用
const sourceFilePart1Md5 = await getFileMd5(sourceFilePath, 0, 1024);
const tempFilePart1Md5 = await getFileMd5(tempFilePath, 0, 1024);
console.log(sourceFilePart1Md5, '---md5-part1---', tempFilePart1Md5);
if (sourceFileSize <= 1024) { // 校验整个文件的md5
if (sourceFilePart1Md5 == tempFilePart1Md5) {
flag = true;
}
} else {
const sourceFilePart2Md5 = await getFileMd5(sourceFilePath, sourceFileSize - 1024, 1024);
const tempFilePart2Md5 = await getFileMd5(tempFilePath, sourceFileSize - 1024, 1024);
console.log(sourceFilePart2Md5, '---md5-part2---', tempFilePart2Md5);
if (sourceFilePart1Md5 == tempFilePart1Md5 && sourceFilePart2Md5 == tempFilePart2Md5) {
flag = true;
}
}
}
console.log(sourceFileSize, '---文件大小---', tempFileSize);
}
return flag;
}