为何MySQL与Perl的Base64编码结果存在差异?
SHA-1 Base64编码结果差异:Perl vs MySQL
问题背景
对同一ASCII字符串'test',Perl和MySQL生成的SHA-1 Base64编码结果不一致,具体代码及输出如下:
Perl代码及输出
#!/usr/bin/env perl use Digest; say Digest->new( 'SHA-1' )->add('test')->b64digest; # 输出: qUqP5cyxm6YcTAhz05Hph5gvu9M
MySQL语句及输出
SELECT TO_BASE64(SHA1('test')); # 输出: YTk0YThmZTVjY2IxOWJhNjFjNGMwODczZDM5MWU5ODc5ODJmYmJkMw==
请问造成这种差异的原因是什么?
原因分析
这问题我之前也碰到过,核心是两者对SHA-1哈希结果的处理逻辑完全不一样,给你拆解下:
Perl的
Digest模块处理逻辑
Perl的b64digest方法是直接对SHA-1生成的原始二进制哈希值进行Base64编码。SHA-1本身会生成20字节的原始二进制数据,b64digest直接将这串二进制数据转换为Base64字符串,所以得到了qUqP5cyxm6YcTAhz05Hph5gvu9M。MySQL的函数处理逻辑
MySQL的SHA1()函数默认返回的是哈希值的十六进制字符串表示(比如'test'的SHA-1十六进制为a94a8fe5ccb19ba61c4c0873d391e987982fbbd3),而非原始二进制数据。后续的TO_BASE64()函数是对这个十六进制字符串(本质是ASCII字符序列)进行Base64编码,而非对原始二进制哈希值编码,这就导致最终结果与Perl产生差异。
统一结果的验证方法
如果想要让MySQL的输出与Perl一致,只需先将SHA1()返回的十六进制字符串转换为二进制数据,再进行Base64编码即可,使用UNHEX()函数实现转换:
SELECT TO_BASE64(UNHEX(SHA1('test'))); # 输出: qUqP5cyxm6YcTAhz05Hph5gvu9M
执行这条语句后,得到的结果就和Perl的完全匹配了。
内容的提问来源于stack exchange,提问作者Paul Serikov
相关产品推荐
相关产品推荐

