Ami*_*ahi 10 filesystems checksum
据我所知,即使更改一点文件,也会更改整个校验和结果,但是当我更改文件名时,这不会影响其校验和(我尝试过 SHA-1、SHA-256 和 MD5)。
为什么?文件名不是文件数据的一部分?它依赖于文件系统吗?
Kus*_*nda 41
文件的名称是目录条目中的字符串,并且许多其他元数据(文件类型、权限、所有权、时间戳等)存储在 inode 中。因此,文件名不是构成文件实际数据的一部分。事实上,单个文件在文件系统中可能有任意数量的名称(硬链接),并且还可以通过任意数量的任意命名的符号链接访问。
由于文件名不是文件数据的一部分,因此当您使用md5
或md5sum
或某些类似实用程序计算例如 MD5 校验和时,它不会自动包含在内。
因此,更改文件的名称(或所有权、时间戳或权限等)或通过其其他名称或符号链接之一访问它(如果有),不会对文件的 MD5 校验和产生任何影响。
ctr*_*lor 10
是的,正如您所说的“文件名不是文件数据的一部分”
文件名不能存储在文件中。如果是,那么它将更改文件。然而,对文件名、其他元数据和文件数据进行校验和可能是有效的,但这通常是一个坏主意。
文件名是其包含目录的一部分。不是文件的一部分。
(可能不是一个好主意)
echo "$filename" | xargs -n1 -I{} bash -c 'echo "$1"; cat "$1"' x {} | shasum
ilk*_*chu 10
当我更改文件名时,这不会影响其校验和(我尝试过 SHA-1、SHA-256 和 MD5)。
嗯,这有点虚假的联系。SHA-1、SHA-256 和 MD5 不计算文件或文件名的哈希值,它们计算比特流的哈希值。所以,你得到的结果完全取决于你选择提供什么作为输入,而你没有表现出来。
现在,您可能使用了sha1sum
,sha256sum
和md5sum
实用程序,实际上它们只在要散列的数据中包含给定文件的内容。不是文件名,不是权限位、所有者信息、时间戳或其他元数据。
不过,这并不具有进行这样做。这是两个文件及其名称的 SHA-256 哈希值:
$ echo hello > a.txt; cp a.txt b.txt
$ ./checksum.sh a.txt b.txt
aed49f7730ca0736fe1a021375d1ca9b509a4e72910b422578df8b4b1930aeca -
bad46702033923726add35ef8d97570f1aa40d93dad1d6ba63e7b051a34b9efc -
Run Code Online (Sandbox Code Playgroud)
该脚本只是将文件名添加到散列数据中。另一个应用程序可以在散列输入中包含元数据以及文件内容,或者包含仅覆盖部分数据的散列。
显然,包含文件名的缺点是即使是同一个文件也可能被不同的名称引用,因此可能有许多不同的哈希值:
/tmp/test$ ./checksum.sh a.txt ./a.txt /tmp/test/a.txt
aed49f7730ca0736fe1a021375d1ca9b509a4e72910b422578df8b4b1930aeca -
85ec58226886f4f853212b2d21bb2fb72447813ac13a59e9376b2e0c02074839 -
25c1c072481131e07c3fc20d16109472872233f658f4df3c4982fb195a048b96 -
Run Code Online (Sandbox Code Playgroud)
在等式中添加时间戳、所有者等几乎可以保证在将文件复制到另一个系统后散列是不同的,这使得散列的有用性相当可疑。甚至文件名也可能丢失或更改。
如果您想将元数据包含在散列中,最简单的方法可能是将文件放入 tar 存档或其他存储您认为有用的元数据的容器中,然后进行散列和复制。从存档中提取文件(内容)后,文件系统上的元数据可能不同,但您仍然可以验证文件来自哪个存档。
上面的脚本是:
$ cat checksum.sh
#!/bin/bash
for f in "$@"; do
(printf "%s\0" "$f" ; cat "$f") | sha256sum -
done
Run Code Online (Sandbox Code Playgroud)