相关疑难解决方法(0)

SQL中二进制字符串的汉明距离

我的数据库中有一个表,我将SHA256哈希存储在BINARY(32)列中.我正在寻找一种方法来计算列中条目的汉明距离到提供的值,即:

SELECT * FROM table 
  ORDER BY HAMMINGDISTANCE(hash, UNHEX(<insert supplied sha256 hash here>)) ASC 
  LIMIT 10
Run Code Online (Sandbox Code Playgroud)

(如果您想知道,字符串A和B的汉明距离定义为BIT_COUNT(A^B),其中^是按位XOR运算符,BIT_COUNT返回二进制字符串中的1的数量).

现在,我知道^运算符和BIT_COUNT函数都只能在INTEGER上运行,所以我想说可能唯一的方法就是分解子字符串中的二进制字符串,将每个二进制子字符串转换为整数,计算汉明距离子串,然后添加它们.这个问题是它听起来非常复杂,效率不高,绝对不优雅.因此,我的问题是:你能提出更好的建议吗?(请注意我在共享主机上,因此我无法修改数据库服务器或加载库)

编辑(1):显然在PHP中加载整个表并进行计算是可能的,但我宁愿避免它,因为这个表可能会变得非常大.

编辑(2):数据库服务器是MySQL 5.1

编辑(3):我的答案包含我刚才描述的代码.

编辑(4):我刚刚发现使用4个BIGINT来存储哈希而不是BINARY(32)会产生大量的速度提升(速度提高100倍以上).请参阅下面的评论.

mysql sql hash binary-data hamming-distance

23
推荐指数
1
解决办法
8374
查看次数

如何计算 MySQL 查询中两个散列之间的差异?

我正在尝试计算输入散列和数据库存储的散列之间的汉明距离。这些是感知散列,因此它们之间的汉明距离对我很重要,并告诉我两个不同图像的相似程度(参见http://en.wikipedia.org/wiki/Perceptual_hashinghttp://jenssegers.com/61/感知图像哈希http://stackoverflow.com/questions/21037578/)。哈希是 16 个十六进制字符长,如下所示:

b1d0c44a4eb5b5a9
1f69f25228ed4a31
751a0b19f0c2783f

我的数据库看起来像这样:

CREATE TABLE `hashes` (
  `id` int(11) NOT NULL,
  `hash` binary(8) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

INSERT INTO `hashes` (`id`, `hash`) VALUES
    (1, 0xb1d0c44a4eb5b5a9),
    (2, 0x1f69f25228ed4a31),
    (3, 0x751a0b19f0c2783f);
Run Code Online (Sandbox Code Playgroud)

现在,我知道我可以像这样查询汉明距离:

SELECT BIT_COUNT(0xb1d0c44a4eb5b5a9 ^ 0x751a0b19f0c2783f)
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,它将输出 38。但是,我似乎无法为此比较引用列名。以下不按预期工作。

SELECT BIT_COUNT(hash ^ 0x751a0b19f0c2783f) FROM hashes
Run Code Online (Sandbox Code Playgroud)

有谁知道如何SELECT使用我的数据库中的列像上面的第一个查询一样计算汉明距离?我试着使用的场景无数hex()unhex()conv(),并cast()以不同的方式。这是在 MySQL 中。

更新我上面的查询在 MySQL v8 中运行时似乎按预期工作(感谢@LukStorms 指出这一点)。您可以使用我下面的小提琴并更改左上角的版本。我现在的问题是:如何确保该行为适用于所有版本的 MySQL?

小提琴:https : //www.db-fiddle.com/f/mpqsUpZ1sv2kmvRwJrK5xL/0

mysql hash bit-manipulation hamming-distance phash

5
推荐指数
1
解决办法
1218
查看次数