假设readFileSync只读取文件的内容,如何将整个文件读取为字节或十六进制字符


Node.js FS的文档说NodeJS的readFileSync只返回目标文件的内容。该链接指向readFile的文档,但关于readFileSync的部分表示参考readFile的文档。据称,NodeJSreadFile"异步读取文件的全部内容">

我想生成一个文件的哈希。我使用crypto库,但愿意使用其他库或方法。哈希不能仅基于文件的内容。它必须使用文件本身的所有字节。例如,假设路径针对的是使用Microsoft PE格式的文件。文件头中表示MachineNumberOfSections等的字节应用于哈希中。我想对文本文件执行此操作。此外,这是微软关于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;
}

最新更新