我正在使用 MySql 5.5.32 并尝试在我们在业务层中拥有的存储过程中重现一些代码,以便我可以为使用sql
. 不过,SHA2 函数似乎有问题,但也许我遗漏了一些东西:
SELECT length(SHA2("bob", 512))
返回 128。不应该是 64 吗?
SELECT length(SHA2("bob", 256))
它返回 64,因此看来要么我遗漏了某些东西,要么 SHA2 中存在错误。有任何想法吗?
评论是正确的,即使文档说它返回二进制字符串,它也会返回十六进制编码的字符串。要获得正确的长度,请使用:
SELECT length(unhex(SHA2("bob", 512)));
我在 2005 年为 SHA2() 函数编写了补丁并将其贡献给 MySQL(然后开发人员对我的代码进行了一些编辑以符合他们的编码标准)。
该函数总是返回一串十六进制数字,就像 MySQL 中的所有其他哈希函数一样。
您可能正在阅读文档中的此声明:
从 MySQL 5.5.6 开始,返回值是连接字符集中的非二进制字符串。在 5.5.6 之前,返回值是二进制字符串。
我可以看到读者会如何认为这意味着它返回二进制字节,但这是一种误解。
这实际上意味着该字符串具有二进制字符集。它仍然是十六进制数字的明文字符串。事实上,MySQL 中的散列函数都没有返回字节字符串,就像您在其上运行 UNHEX() 一样,它们都返回十六进制数字字符串。一串十六进制数字的长度是等效二进制字节长度的两倍。
如果您不知道我所说的二进制字符集,请参阅什么是二进制字符集?
SHA2() 在 5.5.6 中更改为使用连接字符集,而其他哈希函数在 5.5.3 中以相同的方式更改。
SHA2(str, hash_length)函数返回一个非二进制字符串。以前MySQL中的SHA2
函数返回一个二进制字符串的值。
从我提供的链接中的文档:
从 MySQL 5.5.6 开始,返回值是连接字符集中的非二进制字符串。
我们可以通过以下SELECT
语句剖析所有这些:
SELECT SHA2("bob", 256) AS 'Hashed String',
UNHEX(SHA2("bob", 256)) AS 'Binary String',
LENGTH(UNHEX(SHA2("bob", 256))) AS 'Byte Count'
通过MySQL Workbench的输出将导致:
更新每条评论:
UNHEX (str)函数在文档中声明它将输入字符串中的每对字符解释为十六进制数字。至于输入字符串是二进制还是非二进制,文档在这里为我们回答了这个问题:
如果 UNHEX() 的参数是 BINARY 列,则可能出现 NULL 结果,因为值在存储时用 0x00 字节填充,但在检索时不会剥离这些字节。