问题的标题说明了一切。我一直在研究SHA-1和大多数地方,我看到它是40个十六进制字符长,对我来说是640bit。它只能用10个十六进制字符160bit = 20byte来表示。一个十六进制字符可以表示2个字节对吗?为什么它需要的时间是它的两倍?我的理解中缺少什么。
如果使用Base32或Base36,SHA-1甚至不能只有5个或更少的字符?
答案 0 :(得分:82)
一个十六进制字符只能表示16个不同的值,即4位。 (16 = 2 4 )
40×4 = 160。
不,你需要在base-36中使用超过5个字符。
共有2个 160 不同的SHA-1哈希值。
2 160 = 16 40 ,所以这是我们需要40个十六进制数字的另一个原因。
但是2 160 = 36 160 log 36 2 = 36 30.9482 ... ,所以你仍然使用base-36需要31个字符。
答案 1 :(得分:12)
我认为OP的混淆来自表示SHA1哈希的字符串需要40个字节(至少如果你使用的是ASCII),它等于320位(不是640位)。
原因是哈希是二进制的,十六进制字符串只是一个编码。因此,如果您使用更高效的编码(或根本不使用编码),您只需要160位空间(20个字节),但问题是它不是二进制安全的。
你可以使用base64,在这种情况下你需要大约27-28个字节(或字符)而不是40个(见this page)。
答案 2 :(得分:9)
每个8位字节有两个十六进制字符,而不是每个十六进制字符两个字节。
如果使用8位字节(如在SHA-1定义中),则十六进制字符在一个字节内编码单个高或低4位半字节。所以整个字节需要两个这样的字符。
答案 3 :(得分:5)
2个十六进制字符的范围为0-255,即0x00 == 0和0xFF == 255.因此,2个十六进制字符为8位,这使得SHA摘要为160位。
答案 4 :(得分:3)
SHA-1是160位
转换为20个字节= 40个十六进制字符(每个字节2个十六进制字符)
答案 5 :(得分:3)
我的回答与我之前的理论有所不同,关于OP混淆的确切原因,以及我提供的解释的婴儿步骤。
字符根据使用的编码(see here)占用不同的字节数。这些天我们每个字符使用2个字节时有一些上下文,例如用Java编程时(here's why)。因此,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哈希的长度。