由于制作完整二进制文件的哈希值太大而无法在相当快的时间内进行计算:
散列文件的文件信息是什么?以下列出了理想情况下最终散列的属性:
根据经验,我们用来创建足够熵的信息越少越好。由于特定信息的检索速度很大程度上取决于给定的环境(OS,语言的文件IO,所用库的IO等),因此在此不应该忽略它。
(这是我在社区维基上的第一次尝试。我的理由是,这里提到的信息非常通用,但(希望)提供信息。我也希望将这个问题标记为社区维基,所以它可以在适合的地方得到改善。)
答案 0 :(得分:1)
我们的目标是在不使用冗余数据的情况下跟踪两个文件状态之间的差异。因此,每个信息源必须是文件状态信息的脱节子集。
以下各项代表有关文件的信息来源:
文件的名称是其绝对文件系统路径(最后一位)的一部分,正如@ La-comadreja所说,它的独特之处在于系统上没有两个文件可以具有相同的绝对路径。强烈建议使用File的名称与其绝对路径的其余部分(请参阅directory-path以获取更多信息)来避免与其他文件的哈希冲突。
虽然文件绝对路径将是完全唯一的,但应注意在某些情况下散列绝对路径可能是不合适的。例如,当两个文件在两台机器上没有相同的绝对路径时,比较不同机器上两个文件的哈希很可能会失败。这在具有不同OS和/或架构的机器上变得更加成问题。因此,鼓励指定文档根并从中解析绝对路径。
如果要跟踪对文件权限的更改,下面的测试表明您需要将它们直接包含在哈希中,因为它们不会更改有关该文件的任何其他信息(最明显的是时间戳)。但请注意,在不同的计算机上处理权限的方式完全不同,因此必须谨慎行事(例如,使用规范的权限转换方案)。
所有权,就像权限一样,在体系结构和文件系统之间的处理方式也大不相同。所有权变更不会改变其他信息(如下面的测试所示)。
文件的时间戳也是在所有(或至少是最常见的)系统上不统一实现的。首先,我们可以看到的不同文件系统上有不同的时间戳:创建日期,修改日期,访问日期等。为了我们的目的,修改日期是最合适的,因为它受大多数可用文件系统的支持{{ 3}}并保存我们需要的确切信息:文件的最后一次更改。但是,比较不同操作系统中的文件可能会产生问题,因为Windows和Unix处理时间戳(通常)不同(请参阅此处[1]以获取有关该问题的详细文章)。请注意,无论何时编辑文件(忽略边缘情况),文件的修改日期都会更改,因此时间戳表示文件大小的更改(请注意,相反的情况不成立,请参阅文件大小)。
文件大小(以字节为单位)非常好地指示文件是否已被编辑(权限,所有权和名称更改除外),因为每次编辑都会更改文件内容,从而更改其大小。但是,如果对文件的添加与删除完全一样大,则不适用。因此,文件时间戳可能是更好的指标。此外,计算文件二进制大小可能是计算密集型的。
如果想要跨多个主机比较文件并将不同主机上的相同文件视为不同,则该机器的主机名(或主机的另一个合适的唯一标识符)应包含在散列中。
当然,文件的二进制数据具有检查文件是否已更改的所有必要信息。但是,它也太资源密集,不具备任何实用性。我非常劝阻使用这些信息。
以下来源应用于比较文件:
以下额外资源可用于跟踪更多信息:
以下信息来源应予以忽视:
我对Debian进行了一些测试,检查更改一个信息是否会改变另一个信息。最有趣的是,重命名,权限更改,所有者更改不会影响时间戳更改或文件大小更改< / strong>即可。 (请注意,这些测试目前仅在Debian Linux上进行测试。其他操作系统的行为可能会有所不同。)
$ ls -l
-rw-r--r-- 1 alex alex 30 Apr 26 11:04 bar
-rw-r--r-- 1 alex alex 0 Apr 26 11:03 baz
-rw-r--r-- 1 alex alex 14 Apr 26 11:04 foo
$ mv baz baz2
$ ls -l
-rw-r--r-- 1 alex alex 30 Apr 26 11:04 bar
-rw-r--r-- 1 alex alex 0 Apr 26 11:03 baz2
-rw-r--r-- 1 alex alex 14 Apr 26 11:04 foo
$ chmod 777 foo
$ ls -l
-rw-r--r-- 1 alex alex 30 Apr 26 11:04 bar
-rw-r--r-- 1 alex alex 0 Apr 26 11:03 baz2
-rwxrwxrwx 1 alex alex 14 Apr 26 11:04 foo
$ mv baz2 baz
$ echo "Another string" >> bar
$ ls -l
-rw-r--r-- 1 alex alex 45 Apr 26 11:17 bar
-rw-r--r-- 1 alex alex 0 Apr 26 11:03 baz
-rwxrwxrwx 1 alex alex 14 Apr 26 11:04 foo
$ sudo chown root baz
$ ls -l
-rw-r--r-- 1 alex alex 45 Apr 26 11:17 bar
-rw-r--r-- 1 root alex 0 Apr 26 11:03 baz
-rwxrwxrwx 1 alex alex 14 Apr 26 11:04 foo
答案 1 :(得分:0)
假设所有文件都在同一台机器上,目录路径和文件名应该产生唯一的组合,因为同一目录中的两个文件不能具有相同的名称。上次更改的目录路径,文件名和时间戳应捕获每个更改。
如果文件位于不同的计算机上,则计算机名称应包含在目录路径中。