Encoding 如果SHA-1散列只有160位,为什么它的长度是40个字符?

Encoding 如果SHA-1散列只有160位,为什么它的长度是40个字符?,encoding,hash,sha1,hashcode,base32,Encoding,Hash,Sha1,Hashcode,Base32,问题的标题说明了一切。我一直在研究SHA-1,大多数地方我看到它是40个十六进制字符长,对我来说是640位。它不能仅仅用10个十六进制字符160bit=20字节来表示吗。一个十六进制字符可以代表2字节,对吗?为什么它的长度是需要的两倍?我的理解中缺少了什么 如果使用Base32或Base36,SHA-1不能只有5个或更少的字符吗?一个十六进制字符只能代表16个不同的值,即4位。(16=24) 40×4=160 不,在base-36中需要的字符远远超过5个 总共有2160个不同的SHA-1哈希

问题的标题说明了一切。我一直在研究SHA-1,大多数地方我看到它是40个十六进制字符长,对我来说是640位。它不能仅仅用10个十六进制字符160bit=20字节来表示吗。一个十六进制字符可以代表2字节,对吗?为什么它的长度是需要的两倍?我的理解中缺少了什么


如果使用Base32或Base36,SHA-1不能只有5个或更少的字符吗?

一个十六进制字符只能代表16个不同的值,即4位。(16=24)

40×4=160


不,在base-36中需要的字符远远超过5个

总共有2160个不同的SHA-1哈希

2160=1640,这是我们需要40个十六进制数字的另一个原因


但是2160=36160 log362=3630.9482…,所以使用base-36仍然需要31个字符。

2个十六进制字符组成了0-255的范围,即0x00==0和0xFF==255。因此,2个十六进制字符是8位的,这使您的SHA摘要为160位。

每个8位字节有两个十六进制字符,而不是每个十六进制字符有两个字节


如果您使用的是8位字节(如SHA-1定义中所示),则十六进制字符对字节内的单个高或低4位半字节进行编码。因此,一个完整字节需要两个这样的字符。

我认为OP的混淆来自一个表示SHA1哈希的字符串,它需要40个字节(至少如果您使用ASCII),即320位(而不是640位)

原因是哈希是二进制的,十六进制字符串只是二进制的编码。因此,如果要使用更有效的编码(或者根本不编码),可能只需要160位的空间(20字节),但问题是它不会是二进制安全的

不过,您可以使用base64,在这种情况下,您需要大约27-28个字节(或字符),而不是40个字节(请参阅)。

SHA-1是160位


也就是说,20个字节=40个十六进制字符(每个字节2个十六进制字符)

我的回答与之前的理论不同,只是关于OP混淆的确切来源,在我提供的小步骤中,我进行了说明

字符占用的字节数不同,具体取决于所使用的编码()。现在有一些情况下,我们每个字符使用2个字节,例如在Java()中编程时。因此,根据OP的计算,40个Java字符将等于80字节=640位,而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散列的长度。

如果使用base
4.3e9
@NullUserException:不幸的是,我在大约2.09e6的基础上用完了数字。非常感谢你的解释,我知道我的数学一定是错的。我已经有几年没有做过严肃的数学了。有趣的是,如果你将字符集增加了一倍(从16到36),你会期望结果字符串的大小超过其原始大小的一半,但它实际上没有发生(从40到31)。。。