readFileSync
只返回目标文件的内容。该链接指向readFile
的文档,但关于readFileSync
的部分表示参考readFile
的文档。据称,NodeJSreadFile
"异步读取文件的全部内容">
我想生成一个文件的哈希。我使用crypto
库,但愿意使用其他库或方法。哈希不能仅基于文件的内容。它必须使用文件本身的所有字节。例如,假设路径针对的是使用Microsoft PE格式的文件。文件头中表示Machine
、NumberOfSections
等的字节应用于哈希中。我想对文本文件执行此操作。此外,这是微软关于PE格式的文章的链接:PE格式。因此,下面的代码将很少的字节打印到控制台,这意味着只读取内容。
const crypto = require('crypto')
function hash (path) {
const hash_object = crypto.createHash('sha256');
const file_as_buffer = fs.readFileSync(path)
hash_object.update(file_as_buffer);
const hash_string = hash_object.digest('hex');
console.log("Has input", file_as_buffer);
return hash_string;
}
hash('test.txt');
假设文件只包含换行符,则控制台中的输出为一个字节。如何使用表示整个文本文件的字节(包括作者和创建日期等元数据(作为哈希函数的输入?
我确认,在文件的相同副本上,使用上面的代码为同一文件的不同副本返回相同的哈希。即使它们的文件名不同或创建间隔几分钟,也会发生这种情况。我该如何避免这种情况?
如果您需要具有相同内容的不同文件的哈希不同,则必须考虑可以从fs.stat
获得的文件元数据。
function hash (path) {
const hash_object = crypto.createHash('sha256');
const file_as_buffer = fs.readFileSync(path);
const file_meta = fs.statSync(path); // Get file stats
const allFile = Buffer.concat([file_as_buffer, Buffer.from(JSON.stringify(file_meta))]); //Add them to the input buffer for hashing
hash_object.update(allFile);
const hash_string = hash_object.digest('hex');
console.log("Has input", file_as_buffer);
return hash_string;
}
这是我使用的最后一个答案。这和查理的回答几乎一样。我刚刚接受了评论中的建议,从fs.statSync
的结果中选择具体的项目。我取了mtime
(我认为是时间修改的(、ctime
(创建的时间(和size
的总和。接下来的操作都在一行中完成。我明确地将总和转换为字符串,并从该字符串创建了一个缓冲区。最后,我连接了两个缓冲区。
function hash(path: string): string {
const hash_object = crypto.createHash('sha256');
const file_as_buffer = fs.readFileSync(path)
let blockfile_stat = fs.statSync(path);
let blockfile_stat_num: number = blockfile_stat.mtimeMs +
blockfile_stat.ctimeMs + blockfile_stat.size;
hash_object.update(Buffer.concat(
[file_as_buffer, Buffer.from(String(blockfile_stat_num))])
);
const hash_string = hash_object.digest('hex');
return hash_string;
}