这个问题的标题已经说得很清楚了。我一直在研究SHA-1,大多数地方看到的都是由40个十六进制字符组成,对我来说这是640位。它不能只用10个十六进制字符表示吗?160位=20字节。而一个十六进制字符可以表示2个字节,对吧?为什么长度是需要的两倍呢?我的理解哪里错了吗?
如果使用Base32或Base36,SHA-1是否可以甚至只有5个或更少的字符?
一个十六进制字符只能表示16个不同的值,即4位二进制数。(16 = 24)
40 * 4 = 160。
不,你需要比36进制更多的5个字符。
共有2160种不同的SHA-1哈希值。
2160 = 1640,这就是为什么我们需要40个十六进制数字的另一个原因。
但2160 = 36160 log362 = 3630.9482...,因此仍需要使用36进制中的31个字符。
我认为OP的困惑来自于表示SHA1哈希的字符串占用40个字节(至少在使用ASCII时),相当于320位(而不是640位)。
原因在于哈希值是以二进制方式存储的,而十六进制字符串只是对其进行编码。因此,如果您使用更高效的编码(或根本不使用编码),则可以仅使用160位空间(20个字节),但这样做的问题是它不是二进制安全的。
您可以使用base64,这样您只需大约27-28个字节(或字符),而不是40个字节(请参见此页面)。
每8位字节有两个十六进制字符,而不是每个十六进制字符有两个字节。
如果您正在处理8位字节(如SHA-1定义中),那么一个十六进制字符编码一个字节内的单个高位或低位4位二进制数。因此,一个完整的字节需要两个这样的字符。
我的回答与之前的回答不同之处在于我对问题产生困惑的确切原因的理论解释,以及我提供的逐步解释方法。
一个字符所占用的字节数取决于所使用的编码方式(请参见此处)。现在有一些情况下我们使用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
两个十六进制字符组成了0-255的范围,即0x00 == 0,0xFF == 255。因此,2个十六进制字符为8位,这使得您的SHA摘要为160位。
SHA-1是160位。
这相当于20个字节=40个十六进制字符(每个字节2个十六进制字符)。