我很好奇为什么SHA256的结果可以保存在binary(32)
内,但需要varchar(64)
才能保存相同的结果。
我的意思是,256位是32字节,因此,保存在binary(32)
内是完全合理的。但是,为什么尝试将其保存在varchar
中需要为每个字节添加一个额外的字节?
答案 0 :(得分:4)
让我们从头开始看看加密函数是什么以及实际输出的是什么:
加密散列函数是散列函数,即a 采用任意数据块并返回一个数据的算法 固定大小的位串,(加密)哈希值。
这意味着我们获得了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个字节。
希望这有点清除它。它实际上比听起来更简单:)