when I change a file's name this does not affect its checksum (I've tried SHA-1, SHA-256 and MD5).
Well, this is somewhat a false connection. SHA-1, SHA-256 and MD5 don't calculate hashes of files or file names, they calculate hashes of bit streams. So, the result you get depends entirely on what you choose to give as the input, and you didn't show that.
Now, you perhaps used the sha1sum
, sha256sum
and md5sum
utilities, and indeed they only include the contents of the given file in the data to be hashed. Not the file name, not the permission bits, owner information, timestamps or other metadata.
But it doesn't have to be done like that. Here's the SHA-256 hashes of two files and their names:
$ echo hello > a.txt; cp a.txt b.txt
$ ./checksum.sh a.txt b.txt
aed49f7730ca0736fe1a021375d1ca9b509a4e72910b422578df8b4b1930aeca -
bad46702033923726add35ef8d97570f1aa40d93dad1d6ba63e7b051a34b9efc -
The script simply prepends the file names to the hashed data. Another application could include metadata in the hash input along with the file contents, or include hashes that only cover part of the data.
Obviously, including the file name has the disadvantage that even the very same file can be referenced to by different names and can hence have numerous distinct hashes:
/tmp/test$ ./checksum.sh a.txt ./a.txt /tmp/test/a.txt
aed49f7730ca0736fe1a021375d1ca9b509a4e72910b422578df8b4b1930aeca -
85ec58226886f4f853212b2d21bb2fb72447813ac13a59e9376b2e0c02074839 -
25c1c072481131e07c3fc20d16109472872233f658f4df3c4982fb195a048b96 -
Adding timestamps, owners and such to the equation would almost guarantee the hashes being different after the file was copied to another system, making the usefulness of the hash rather questionable. Even the file name might get lost or changed.
If you want to include the metadata in the hash, it's probably easiest to put the file(s) in a tar archive, or some other container that stores the metadata you find useful, and hash and copy that. After extracting the file (contents) from the archive, the metadata on the file system might be different, but you could still verify the archive the file came from.
The script above is:
$ cat checksum.sh
#!/bin/bash
for f in "$@"; do
(printf "%s\0" "$f" ; cat "$f") | sha256sum -
done