【问题标题】:Hash of folders in nodejsnodejs中文件夹的哈希
【发布时间】:2021-06-21 21:28:20
【问题描述】:

在我的项目中,我想计算文件夹的哈希值。 例如,有 10 个文件夹,这些文件夹有很多子文件。我知道很多方法来获取文件的哈希值,但是有什么方法可以获取每个文件夹的哈希值吗?

我这样做的目的是了解文件夹中的文件是否已更改。

我愿意接受建议和不同的想法,我需要你的帮助。提前致谢。

【问题讨论】:

  • 您是在问如何遍历这些文件夹并获取每个文件的哈希值?
  • 实际上不,我只想从文件夹中的所有文件中提取一个哈希码。我只有一个文件夹,你可以把它想象成一个 react 项目。这个文件夹应该有一个哈希码,我需要了解其中的任何文件是否已更改。难道不单独散列每个文件就可以做到这一点吗?
  • 如果你想对文件的实际内容进行哈希处理,如果不读取每个文件的每个字节并计算每个文件的哈希值或文件夹的组合哈希,就无法做到这一点。我猜你可以只对文件名和文件大小进行哈希处理,并希望这足以检测到更改,但显然长度相同但内容不同(例如更改文件中的一个字符)的文件不会被检测到方式。然后,您可以为每个文件添加修改日期,并可能捕获更多更改。
  • 一个简单的 exec find -type f -exec md5sum "{}" + 将产生带有文件路径的每个散列,find -type f -exec md5sum "{}" + | md5sum | cut -c 1-32 将散列整个路径,另外,如果您在项目提交状态的散列之后获取最近的提交散列git rev-parse HEAD 和/或远程调用git ls-remote origin -h refs/heads/master 并将其与本地git rev-parse refs/heads/master 进行比较

标签: javascript node.js hash hashcode


【解决方案1】:

这实际上取决于您希望修改检测的可靠性。最可靠的方法是遍历每个文件夹中的每个文件,并通过读取每个文件的每个字节来计算实际文件内容的哈希值。

除此之外,您还可以检查文件元数据,例如文件名、修改日期、文件大小。其中任何一个的变化都表明内容发生了变化。但是,其中任何一个都没有变化并不能最终表明文件内容没有改变。可以修改文件内容,保持相同的文件名,保持相同的文件大小,并手动将修改日期设置回原来的样子——从而愚弄只检查元数据。

但是,如果您愿意接受它可能会通过操纵而被愚弄,但通常会检测到更改,那么您可以迭代文件夹的所有文件并计算使用元数据的组合哈希:文件名、文件大小和文件修改日期,并为文件夹提供一个哈希值。根据您的目的,可能不够,也可能不够 - 您必须拨打电话。

除此之外,您将不得不读取每个文件的每个字节并计算实际文件内容的哈希值。

以下是元数据哈希算法的一些演示代码:

const fsp = require("fs/promises");
const { createHash } = require("crypto");
const path = require('path');

// -----------------------------------------------------
// Returns a buffer with a computed hash of all file's metadata:
//    full path, modification time and filesize
// If you pass inputHash, it must be a Hash object from the crypto library
//   and you must then call .digest() on it yourself when you're done
// If you don't pass inputHash, then one will be created automatically
//   and the digest will be returned to you in a Buffer object
// -----------------------------------------------------

async function computeMetaHash(folder, inputHash = null) {
    const hash = inputHash ? inputHash : createHash('sha256');
    const info = await fsp.readdir(folder, { withFileTypes: true });
    // construct a string from the modification date, the filename and the filesize
    for (let item of info) {
        const fullPath = path.join(folder, item.name);
        if (item.isFile()) {
            const statInfo = await fsp.stat(fullPath);
            // compute hash string name:size:mtime
            const fileInfo = `${fullPath}:${statInfo.size}:${statInfo.mtimeMs}`;
            hash.update(fileInfo);
        } else if (item.isDirectory()) {
            // recursively walk sub-folders
            await computeMetaHash(fullPath, hash);
        }
    }
    // if not being called recursively, get the digest and return it as the hash result
    if (!inputHash) {
        return hash.digest();
    }
}

computeMetaHash(__dirname).then(result => {
    console.log(result);
}).catch(err => {
    console.log(err);
});

【讨论】:

  • @rider - 我在答案中添加了演示代码。
  • @rider - 你不需要自己为 inputHash 传递任何东西。它将适当地默认。该参数在递归到嵌套文件夹时在内部使用。
  • @rider - 你必须决定哪种算法适合你。仅文件大小很容易被愚弄。只需编辑文件并更改文件中的一个字符,大小不会改变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-20
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
  • 2013-12-23
  • 2019-05-17
  • 2011-05-27
相关资源
最近更新 更多