4

在查看了用于生成 Java MD5 和 SHA* 哈希的多个在线参考之后,我注意到纯文本(文件字符串)在被馈送到 Digest 对象以生成哈希之前和之后都经过了一定的准备。具体来说,数据首先转换为字节数组,然后馈送到摘要,然后将输出哈希转换为十六进制流。为什么所有这些字节和十六进制转换?

PS:我想答案与 Java 和 Digest 对象如何开展业务有关,我提出这个问题的动机是了解这种行为,并可能获得对一些文档/文献的参考,以深入解释这一点.

丹克!

4

2 回答 2

5

这有两个部分:

  1. 为什么我们在消化之前将字符串转换为字节数组?
  2. 为什么我们将摘要转换为十六进制?

第一个答案是摘要适用于字节数组。他们对字符串、数字或任何其他数据类型一无所知。只是字节。因此,我们获取一个String对象并使用某种形式的文本编码(例如 UTF-8)将其转换为字节数组。

请注意,编码很重要:我可以用 UTF-8、UTF-16、US-ASCII 或任何数量的其他编码对字符串“hello world”进行编码。如果我选择 UTF-8,它将生成 11 个字节的输出(因为“hello world”是 11 个字符长),但 UTF-16 将生成 22 个字节的输出。这两种编码会产生不同的摘要,因此了解编码至关重要。

第二个答案是,摘要通常用于基于字符串的协议(例如 HTTP cookie)中,用于将密码哈希存储在数据库的文本列中,用于将 PGP 签名添加到电子邮件等。

由于摘要生成原始字节数组,因此需要将其重新编码为文本友好的内容。这就是为什么使用十六进制(或更可能是 base-64)的原因。

例如,继续使用“hello world”示例,假设 UTF-8 编码的摘要转换为具有以下值的字节数组:(4 27 125 8 0 22 90 7对于我神话般的 8 字节摘要函数)。如果我试图将其解释为 UTF-8 字符串,那么我会得到很多垃圾:0 不是可打印的字符。以十六进制编码意味着我可以以有意义的方式将其打印出来,或将其添加到我的 PGP 电子邮件或其他任何内容中。

那有意义吗?

于 2013-03-19T03:49:16.320 回答
1

这些散列算法的实现适用于字节,而不是字符串字符之类的其他东西。这就是为什么您需要将所有内容都转换为字节形式的原因。

于 2013-03-19T03:46:37.927 回答