字符串 -> SHA -> base64,通过 cmd 工具 (openssl/xxd/base64) 的 3 种方式和 3 种不同的结果,为什么?


method1:
$echo -n "The quick brown fox jumps over the lazy dog" | openssl sha1 | base64
MmZkNGUxYzY3YTJkMjhmY2VkODQ5ZWUxYmI3NmU3MzkxYjkzZWIxMgo=
method2:
$ echo -n "The quick brown fox jumps over the lazy dog" | openssl sha1 | xxd -r -p | base64
L9ThxnotKPzthJ7hu3bnORuT6xI=
method3:
echo -n "The quick brown fox jumps over the lazy dog" | openssl sha1 | xxd -b -p | base64
MzI2NjY0MzQ2NTMxNjMzNjM3NjEzMjY0MzIzODY2NjM2NTY0MzgzNDM5NjU2NTMxNjI2MjM3MzY2NTM3CjMzMzkzMTYyMzkzMzY1NjIzMTMyMGEK

我基本上是在尝试通过sha1对输入字符串The quick brown fox jumps over the lazy dog进行校验和,然后对结果进行base64校验和,我有上面两种方法,我认为method2是正确的答案,但在我再次将十六进制输入base64之前,我必须通过xxd -r和纯格式-p将其转换回二进制,为什么我必须做这个额外的步骤?

我在任何地方都找不到base64 cmd工具期望输入是二进制的?但让我们假设,当我显式地将其转换为二进制并通过mehod3 xxd -b option将其提供给base64时,结果再次不同。

如果是在编程语言bcos中,这可能会更容易,我们可以完全控制,但通过一些cmd工具,这有点令人困惑,有人能帮我解释一下吗?

这里有三个不同的结果,因为您将向base64传递三个不同字符串。

根据您在base64上提出的期望输入为二进制的问题,@chepner就在这里:

所有数据都是二进制的;文本只是表示文本编码(ASCII、UTF-8等(的字节流。

中介步骤

为了清楚起见,让我们将共享命令存储在一个变量中。

$ msg='The quick brown fox jumps over the lazy dog'
$ sha_val="$(printf "$msg" | openssl sha1 | awk '{ print $2 }')"
$ printf "$sha_val"
2fd4e1c67a2d28fced849ee1bb76e7391b93eb12

需要注意的几件事:

  • 使用printf是因为它更一致,尤其是当我们比较字节和哈希时
  • 作为openssl连接到awk '{ print $2 }'的管道可能会以(stdin)=为前缀

比较字节

我们可以使用xxd来比较每个字节,使用-c 1000来使用1000个字符行(即不要为<1000个字符字符串添加换行符(。这对于像方法2中的输出这样的字符串很有用,因为其中存在无法打印的控制字符。

方法1

这是sha值的十六进制表示。例如,sha输出中的第一个2在此结果中是32,因为十六进制32<=>dec 50<=>ASCII/UTF-8"2"。如果这令人困惑,请查看ASCII表。

$ printf "$sha_val" | xxd -p -c 1000
32666434653163363761326432386663656438343965653162623736653733393162393365623132

方法2

这个输出与$sha_val完全相同,假设我们从十六进制转换为ASCII二进制,然后用xxd返回。请注意,对于base64,不需要将sha值从十六进制转换为二进制。

$ printf "$sha_val" | xxd -r -p | xxd -p -c 1000
2fd4e1c67a2d28fced849ee1bb76e7391b93eb12

方法3

xxd的-p选项覆盖-b选项,因此xxd -b -p<=>CCD_ 16。

$ printf "$sha_val$" | xxd -p -c 1000 | xxd -p -c 1000
33323636363433343635333136333336333736313332363433323338363636333635363433383334333936353635333136323632333733363635333733333339333136323339333336353632333133323061

如您所见,base64生成三个不同的字符串,因为它接收三个不同字符串。

最新更新