【问题标题】:Length of the result of SHA256 algoSHA256 算法结果的长度
【发布时间】:2012-10-02 20:56:23
【问题描述】:

我很好奇为什么 SHA256 的结果可以保存在 binary(32) 中,但它需要 varchar(64) 才能保存相同的结果。

我的意思是,256 位是 32 字节,因此,保存在 binary(32) 中非常有意义。但是,为什么要尝试将其保存在 varchar 中,每个字节都需要一个额外的字节呢?

【问题讨论】:

  • 因为您收到的散列实际上是一个数字。当以二进制格式表示时,该数字是 1 和 0 的序列。但是,当您希望它通过字符表示时,对于十六进制数,您需要两个字符。这就是为什么二进制输出是 32 字节,字符一是 64。
  • 我还是不明白。我正在尝试查看实际的原始数据,所以我使用的是 Python 的控制台。写入a = 0b10101111 将使a 取值175(十进制)。以十六进制表示的相同值是 0xaf -> hex(0b10101111)。所以我有 8 个二进制字节,我以十六进制的 0xaf 结尾。所有丢失的字节在哪里?
  • 1 字节 = 10101111。当您获得原始输出时,原始输出的 1 个“字符”代表 10101111。有32个这样的“字符”。当通过各种编辑器直接查看时,它们看起来是乱码,但是您可以将它们存储在 binary MySQL 列中。但是,对于那 1 个字节,当转换为十六进制时 - 它的字符表示是 AF。因此,它需要 2 个 ASCII 字符来表示。
  • 这是有道理的。谢谢,我现在明白了。
  • 那 1 个字节代表一个数字。当然,这个数字可以用 ASCII 表示,你是对的。但是代码页呢?散列在每个代码页中看起来都一样吗?它不会,127 以上的代码是任意的,并且取决于代码页,并且对大多数人来说是不可读的。所以它必须被解释为一个数字(因为它是一个数字)。但是 ASCII 仅定义 0-9,因此您的数字中的 1 位数字 = 1 个字节。用 ASCII = 3 个字节将 10101111 表示为 175,因为每个数字是 1 个字符。因此,它表示为十六进制数。希望这能澄清一点。

标签: mysql sha256


【解决方案1】:

让我们从头开始,看看密码函数是什么以及它的实际输出是什么:

密码散列函数是一个散列函数,即 采用任意数据块并返回一个 固定大小的位串,(加密)哈希值。

这意味着我们得到了 1 和 0 的序列。为了正确保存该序列,您必须使用 MySQL 的 binary 数据类型列,因为它不保存任何关于如何向用户表示已保存数据的数据 - 没有与之关联的编码。这意味着当您尝试查看数据时,您很可能会看到乱码,因为 GUI 程序会尝试将存储的值表示为 ASCII 编码字符串(这是错误的)。

我将跳过将哈希值表示为数字的原因,但重点是它确实如此。它是一个十六进制数。让我们使用您使用的第一个字节:

10101111 = 十进制 175 或十六进制 AF

当然,您可以将 ASCII 175 表示为某种东西,它很可能是一个奇怪的字符,具体取决于所使用的代码页。 ASCII 的问题在于 127 以上的代码是任意的,这会导致发明代码页,从而导致发明 Unicode 等,所以我现在将跳过它。

重点是,您不能依赖 ASCII 在每种情况下都正确显示 10101111。 这意味着175 必须使用 3 个字节而不是 1 个字节来显示。为什么?因为175 中的每个字符都必须使用自己的字节来显示。

这意味着您可以将哈希值显示为十进制数。这也意味着您可以将您的数字显示为十六进制数字,它的表示时间要短得多。

让我们再来一次10101111

十进制为175,在屏幕上显示它需要3 个字节-1 为1,7 为1,5 为1。 在十六进制中,它是AF,需要 2 个字节才能在屏幕上显示 - 明显更短。

转换为十六进制数字时,每个字节至少有 2 位数字(有前导零)。对于十进制数字,情况并非如此,因此您知道每次要将 1 个字节表示为十六进制数字时 - 您至少有 2 位数字。因此,您的消息是固定宽度的,它使用数字 0-9,字母 A-F 在每个 ASCII 代码页中的相同位置,因此它们看起来相同。

因此,当您将AF 显示为 ASCII 时,A 需要 1 个字节,F 需要 1 个字节。 有 32 个数字,每个数字有 2 个数字,32x2 = 64 个字节。

您可能犯的唯一错误是使用varchar(64)。如果您知道散列宽度,则使用 varchar 存储散列是没有用的。使用char 会更好,因为您不会浪费varchar 列使用的那1 个字节。

希望这能稍微澄清一下。它实际上比听起来更简单:)

【讨论】:

  • 这个答案很完美!现在我真的明白了。
猜你喜欢
  • 2021-02-03
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-12
相关资源
最近更新 更多