如果 SHA-1 哈希值只有 160 位,为什么它却有 40 个字符长?
问题的标题说明了一切。我一直在研究 SHA-1,在大多数地方我看到它是 40 个十六进制字符长,对我来说是 640 位。难道不能只用 10 个十六进制字符来表示 160bit = 20byte 吗?一个十六进制字符可以代表 2 个字节,对吗?为什么它是所需时间的两倍?我的理解中缺少什么。
如果使用 Base32 或 Base36 ,SHA-1 甚至不能只有 5 个或更少的字符吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
一个十六进制字符只能表示16个不同的值,即4位。 (16 = 24)
40 × 4 = 160。
不,您需要 5 个以上的 36 进制字符。
总共有 2160 种不同的 SHA-1 哈希值。
2160 = 1640,所以这是我们需要 40 个十六进制数字的另一个原因。
但是 2160 = 36160 log362 = 3630.9482...,所以你仍然需要 31 个字符使用base-36。
One hex character can only represent 16 different values, i.e. 4 bits. (16 = 24)
40 × 4 = 160.
And no, you need much more than 5 characters in base-36.
There are totally 2160 different SHA-1 hashes.
2160 = 1640, so this is another reason why we need 40 hex digits.
But 2160 = 36160 log362 = 3630.9482..., so you still need 31 characters using base-36.
我认为OP的困惑来自于表示SHA1哈希值的字符串需要40个字节(至少如果您使用ASCII),这等于320位(而不是640位)。
原因是哈希值是二进制的,而十六进制字符串只是其编码。因此,如果您要使用更有效的编码(或根本不编码),则只能占用 160 位空间(20 字节),但问题是它不是二进制安全的。
不过,您可以使用 base64,在这种情况下,您需要大约 27-28 个字节(或字符)而不是 40 个(请参阅
I think the OP's confusion comes from a string representing a SHA1 hash takes 40 bytes (at least if you are using ASCII), which equals 320 bits (not 640 bits).
The reason is that the hash is in binary and the hex string is just an encoding of that. So if you were to use a more efficient encoding (or no encoding at all), you could take only 160 bits of space (20 bytes), but the problem with that is it won't be binary safe.
You could use base64 though, in which case you'd need about 27-28 bytes (or characters) instead of 40 (see this page).
每个 8 位字节有两个十六进制字符,而不是每个十六进制字符有两个字节。
如果您使用 8 位字节(如 SHA-1 定义中所示),则十六进制字符会对字节内的单个高或低 4 位半字节进行编码。所以一个完整的字节需要两个这样的字符。
There are two hex characters per 8-bit-byte, not two bytes per hex character.
If you are working with 8-bit bytes (as in the SHA-1 definition), then a hex character encodes a single high or low 4-bit nibble within a byte. So it takes two such characters for a full byte.
我的答案与之前的答案仅在我的理论中关于OP混乱的确切起源以及我提供的阐明的婴儿步骤中有所不同。
一个字符根据使用的编码占用不同的字节数(原因如下)。因此,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 位:
因此每个十六进制字符只有半个字节,40 个十六进制字符为我们提供了 20 个字节 = 160 位 - SHA-1 哈希的长度。
My answer only differs from the previous ones in my theory as to the EXACT origin of the OP's confusion, and in the baby steps I provide for elucidation.
A character takes up different numbers of bytes depending on the encoding used (see here). There are a few contexts these days when we use 2 bytes per character, for example when programming in Java (here's why). Thus 40 Java characters would equal 80 bytes = 640 bits, the OP's calculation, and 10 Java characters would indeed encapsulate the right amount of information for a SHA-1 hash.
Unlike the thousands of possible Java characters, however, there are only 16 different hex characters, namely 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E and F. But these are not the same as Java characters, and take up far less space than the encodings of the Java characters 0 to 9 and A to F. They are symbols signifying all the possible values represented by just 4 bits:
Thus each hex character is only half a byte, and 40 hex characters gives us 20 bytes = 160 bits - the length of a SHA-1 hash.
2 个十六进制字符组成 0-255 的范围,即 0x00 == 0 和 0xFF == 255。因此 2 个十六进制字符是 8 位,这使得 SHA 摘要为 160 位。
2 hex characters mak up a range from 0-255, i.e. 0x00 == 0 and 0xFF == 255. So 2 hex characters are 8 bit, which makes 160 bit for your SHA digest.
SHA-1 为 160 位
,转换为 20 个字节 = 40 个十六进制字符(每字节 2 个十六进制字符)
SHA-1 is 160 bits
That translates to 20 bytes = 40 hex characters (2 hex characters per byte)