我在数据库中有一个表,其中我在BINARY(32)列中存储SHA256哈希值。我正在寻找一种方法来计算该列条目与提供的值之间的汉明距离,即类似于:
SELECT * FROM table
ORDER BY HAMMINGDISTANCE(hash, UNHEX(<insert supplied sha256 hash here>)) ASC
LIMIT 10
如果你好奇,字符串A和B的汉明距离定义为BIT_COUNT(A^B)
,其中^是按位异或运算符,BIT_COUNT返回二进制字符串中1的数量。
现在,我知道^运算符和BIT_COUNT函数只适用于整数,所以我认为可能唯一的方法是将二进制字符串分成子字符串,将每个二进制子字符串转换为整数,逐个子字符串计算汉明距离,然后相加。问题在于这听起来非常复杂,不高效,绝对不优雅。因此,我的问题是:你能否提出更好的方法?(请注意,我使用的是共享托管,因此无法修改DB服务器或加载库)
编辑(1):显然,在PHP中加载整个表并进行计算是可能的,但我宁愿避免这样做,因为这个表可能会变得非常大。
编辑(2):DB服务器是MySQL 5.1
编辑(3):我的下面的答案包含了我刚才描述的代码。
编辑(4):我刚刚发现,使用4个BIGINT来存储哈希而不是BINARY(32)可以极大地提高速度(超过100倍)。请参见下面对我的答案的评论。