问题的标题说明了一切。我一直在研究 SHA-1,大多数地方我看到它是 40 个十六进制字符长,对我来说是 640 位。仅用 10 个十六进制字符 160 位 = 20 字节就不能很好地表示吗?一个十六进制字符可以代表2个字节对吗?为什么它需要两倍的时间?我的理解中缺少什么。
如果使用 Base32 或 Base36 ,SHA-1 甚至不能只有 5 个或更少的字符吗?
一个十六进制字符只能表示 16 个不同的值,即 4 位。(16 = 2 4 )
40 × 4 = 160。
不,您需要 5 个以上的 base-36 字符。
总共有2160种不同的 SHA-1 哈希。
2 160 = 16 40,所以这是我们需要 40 个十六进制数字的另一个原因。
但是 2 160 = 36 160 log 36 2 = 36 30.9482...,所以你仍然需要使用 base-36 的 31 个字符。
我认为 OP 的困惑来自一个表示 SHA1 哈希的字符串需要 40 个字节(至少如果你使用 ASCII),它等于 320 位(不是 640 位)。
原因是哈希是二进制的,而十六进制字符串只是它的编码。因此,如果您要使用更有效的编码(或根本不使用编码),您可以只占用 160 位空间(20 字节),但问题是它不会是二进制安全的。
不过,您可以使用 base64,在这种情况下,您需要大约 27-28 个字节(或字符)而不是 40 个(参见此页)。
每个 8 位字节有两个十六进制字符,而不是每个十六进制字符两个字节。
如果您使用 8 位字节(如在 SHA-1 定义中),则十六进制字符在一个字节内编码单个高或低 4 位半字节。所以一个完整的字节需要两个这样的字符。
2 个十六进制字符构成 0-255 的范围,即 0x00 == 0 和 0xFF == 255。所以 2 个十六进制字符是 8 位,这为您的 SHA 摘要提供了 160 位。
我的答案仅与我的理论中关于 OP 混乱的确切起源以及我提供阐明的婴儿步骤中的先前答案不同。
一个字符占用不同数量的字节取决于所使用的编码(见这里)。现在有一些情况下我们每个字符使用 2 个字节,例如在 Java 中编程时(这就是原因)。因此 40 个 Java 字符将等于 80 个字节 = 640 位(OP 的计算),而 10 个 Java 字符确实为 SHA-1 哈希封装了适量的信息。
然而,与数千个可能的 Java 字符不同,只有 16 个不同的十六进制字符,即 0、1、2、3、4、5、6、7、8、9、A、B、C、D、E 和 F . 但这些与 Java 字符不同,占用的空间远小于 Java 字符 0 到 9 和 A 到 F 的编码。它们是表示仅用 4 位表示的所有可能值的符号:
0 0000 4 0100 8 1000 C 1100
1 0001 5 0101 9 1001 D 1101
2 0010 6 0110 A 1010 E 1110
3 0011 7 0111 B 1011 F 1111
因此每个十六进制字符只有半个字节,而 40 个十六进制字符给我们 20 字节 = 160 位 - SHA-1 哈希的长度。
SHA-1 是 160 位
转换为 20 个字节 = 40 个十六进制字符(每字节 2 个十六进制字符)