在软件开发过程中,有时候需要随手计算一个文件或字符串的哈希值,例如,密码的哈希值。
我们可以使用各种集成开发环境,不同语言来实现,但是这一过程对于计算哈希值太过繁琐。
文本介绍如何在 macOS 或 Linux 系统中计算字符串和文件的哈希值,以及如何进行验证。
SHA 字符串
$ echo -n "hello" | shasum
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d -
$ echo "hello" | shasum
f572d396fae9206628714fb2ce00f72e94f2258f -
echo 命令的 -n 参数表示不在字符串末尾处添加换行 (newline ) 字符 ('\n')。
这就是计算看似相同的一个字符串,但是实际结果却不相同的原因,因为多了一个不可见的换行符。
SHA 文件
我们再来看看如何计算一个文件的哈希值。
$ echo "hello" > hello1
$ shasum hello1
f572d396fae9206628714fb2ce00f72e94f2258f hello1
$ echo -n "hello" > hello2
$ shasum hello2
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d hello2
让我们查看 hello1 和 hello2 两个文件内容:
$ cat hello1
hello
$ cat hello2
hello$
注意: $ 是命令提示符。
在查看 hello1 文件时,因为文件内容 hello 后面包含了换行符,因此在输出文件内容 hello 时,这个换行符让新命令提示符 $ 换到了下一行,与输出内容 hello 不在同一行。
在查看 hello2 文件时,因为文件内容 hello 后面不包含换行符,使得输出的文件内容 hello 与新命令提示符 $ 位于同一行。
通过对比两个文件的内容,让换行符显出原形。
SHA 更多
在上面计算 SHA 哈希值时,默认使用的是 SHA1 算法。我们还可以通过 shasum 命令的 -a 或者 --algorithm 参数指定不同的 SHA 算法。
$ echo -n "hello" | shasum -a 1
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d -
$ echo -n "hello" | shasum -a 224
ea09ae9cc6768c50fcee903ed054556e5bfc8347907f12598aa24193 -
$ echo -n "hello" | shasum -a 256
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 -
$ echo -n "hello" | shasum -a 384
59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f -
$ echo -n "hello" | shasum -a 512
9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043 -
$ echo -n "hello" | shasum -a 512224
fe8509ed1fb7dcefc27e6ac1a80eddbec4cb3d2c6fe565244374061c -
$ echo -n "hello" | shasum -a 512256
e30d87cfa2a75db545eac4d61baf970366a8357c7f72fa95b52d0accb698f13a -
SHA 实战
我们在网络上下载软件时,经常会发现和软件形影相随的一个或者多个摘要值文件。摘要值文件就是用来验证我们下载的软件是否完整,有没有遭到破坏。
现在我们来模拟这一过程。
上面我们已经创建了一个 hello1 文件,想发不到互联网上,向全世界打个招呼。
为了让用户能够验证所下载文件的内容没有被其他人篡改,我们需要同时发布一个哈希值文件 hello1_sha1.
$ shasum hello1 > hello1_sha1
用户下载到 hello1 和 hello1_sha1 两个文件后,就可以进行验证了。
$ shasum --check hello1_sha1
hello1: OK
注意:hello1 和 hello1_sha1 两个文件需要位于相同目录中。
这里可能会有一个疑问:在验证时,shasum 命令没有接收数据文件 hello1,只接收了哈希值文件 hello1_sha1,两者是如何匹配到呢?
答案就在 hello1_sha1 文件的内容里。
$ cat hello1_sha1
f572d396fae9206628714fb2ce00f72e94f2258f hello1