MD5是128位的,但为什么它只有32个字符?

132

我读了一些关于md5的文档,它说它是128位,但为什么只有32个字符?我无法计算这些字符。

  • 1字节等于8位
  • 如果1个字符等于1个字节
  • 那么128位就是128/8 = 16个字节,对吧?

编辑:

SHA-1产生160位,那么有多少个字符呢?


你可以发布一个你参考的文档链接吗? - Don Roby
@don:抱歉,这是我的讲师笔记。但是ba__friend已经回答了我的问题,并且我在这里测试了它:http://www.miraclesalad.com/webtools/md5.php,它确实只有十六进制字符,现在对我来说更有意义了。我会将他的答案评为最佳答案。 - hash_jr90
我认为我的回答比其他任何回答都更详细。[如果您是新手程序员并提出了这个问题,想要一个全面的答案](https://dev59.com/DG015IYBdhLWcg3w6QLA#41618070) - Evan Carroll
11
这不是一个愚蠢的问题。曾经你也不知道多少个十六进制字符表示一个字节。 - David Klempfner
一个快速计算哈希位长度的Python单行代码是((1 << (n*4))-1).bit_length(),其中n是十六进制哈希的长度。 - Wouterr
9个回答

135

32个字符的十六进制表示,每个字节2个字符。


1
1 字节由两位十六进制数字表示,例如 255 = ff。 - ba__friend
1
所以1个字节等于2个字符,这意味着16位等于2个字符,那么128/16 = 8。因此需要8个2个字符= 16个字符,对吗?为什么是32? - Koray Tugay
24
因为每个十六进制字符可以用4位表示。所以如果是128位,就是128/4=32个十六进制字符。即使每个"char"被编码为utf8或ascii,这将使十六进制表示大小为32*8=256位。 - Gaston Sanchez
4
这是一个非常糟糕的答案。我的回答详细解释了这一点:https://dev59.com/DG015IYBdhLWcg3w6QLA#41618070 - Evan Carroll
@KorayTugay “所以1个字节等于2个字符,这意味着16位等于2个字符” - 1字节 ≠ 16位。 - David Klempfner

46

我想把一些答案总结在一个帖子里。

首先,不要把MD5哈希看作字符字符串,而是看作十六进制数字。因此,每个数字都是一个十六进制数字(0-15或0-F),代表4位,而不是8位。

更进一步,一个字节或8位由两个十六进制数字表示,例如 b'1111 1111' = 0xFF = 255

MD5哈希有128位长度,通常由32个十六进制数字表示。

SHA-1哈希有160位长度,通常由40个十六进制数字表示。

对于SHA-2系列,我认为哈希长度可以是预定集的其中一个。因此,SHA-512可以由128个十六进制数字表示。

再次说明,本帖仅基于以前的答案。


36

一个十六进制的“字符”(nibble)与“字符”不同

为了澄清位,字节和字符的区别。

  • 1个字节等于8个位(就我们而言)
  • 8位提供了2 ** 8种可能的组合:256种组合

当您查看一个十六进制字符时,

  • [0-9]+[a-f]的16种组合:完整范围的0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
  • 16小于256,因此一个十六进制字符不能存储一个字节。
  • 16是2 ** 4:这意味着一个十六进制字符可以在一个字节中存储4个位(半个字节)。
  • 因此,两个十六进制字符可以存储8个位,2 ** 8种组合。
  • 一个表示为十六进制字符的字节是[0-9a-f] [0-9a-f],它表示字节的两半(我们称一个半字节为nibble)。

当您查看一个普通的单字节字符时(我们完全会跳过多字节和宽字符),

  • 如果一个十六进制字符在md5()里都可以存储的话,你会看到所有小写字母、大写字母、标点符号和像 ¡°ÀÐàð 这样的字符,还有空格(例如换行和制表符)以及控制字符(你甚至看不到其中的许多控制字符,因为它们没有被使用)。
  • 所以它们明显是不同的,我希望这提供了最好的区别分析。


    1
    “在哪个顺序下是规范或平台相关的”这句话实际上是什么意思?希望能够有更详细的解释。 - KumarM
    1
    @KumarM 我打算删除它,因为我认为它实际上与对话没有任何关系,并且措辞不当。 - Evan Carroll

    29

    MD5计算出十六进制数字(0-15 / 0-F),因此每个数字占用四位。128 / 4 = 32个字符。

    SHA-1也会计算出十六进制数字(0-15 / 0-F),因此160 / 4 = 40个字符。

    (由于它们是数学运算,所以大多数哈希函数的输出通常表示为十六进制数。)

    你可能在想ASCII文本字符,它们是8位。


    非常感谢!现在我的头脑中有了更加清晰的图像! - hash_jr90
    注意:ascii-charset包含不可打印的符号。 - Roy Lee
    我试图更明确地分解这个问题 https://dev59.com/DG015IYBdhLWcg3w6QLA#41618070 - Evan Carroll

    14

    一个十六进制数字 = 1 四位二进制数(四位二进制数)

    两个十六进制数字 = 1 字节(八位二进制数)

    MD5 = 32 个十六进制数字

    32 个十六进制数字 = 16 字节(32/2)

    16 字节 = 128 位(16 * 8)

    对于SHA-1也是同样的规则,只不过它有40个十六进制数字。

    希望这可以帮到您。


    9
    那是32个十六进制字符——1个十六进制字符等于4位二进制数。

    3
    这些是十六进制数字,而不是字符。一个数字等于4个比特。

    2

    实际上它们不是字符,而是十六进制数字。


    0

    为了清楚地理解,请复制MD5计算的128位哈希值到二进制转十六进制转换器中,查看十六进制值的长度。您将获得32个字符的十六进制字符。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接