У меня есть таблица в моей БД, где я храню хэши SHA256 в столбце BINARY (32). Я ищу способ, чтобы вычислить расстояние Хемминга записей в столбце введённого значения, то есть что-то вроде:Расстояние Хэмминга по двоичным строкам в SQL
SELECT * FROM table
ORDER BY HAMMINGDISTANCE(hash, UNHEX(<insert supplied sha256 hash here>)) ASC
LIMIT 10
(в случае, если вам интересно, расстояние Хемминга строк A и B определяется как BIT_COUNT(A^B)
, где^- побитовый оператор XOR, а BIT_COUNT возвращает число 1 в двоичной строке).
Теперь я знаю, что и функция ^, и функция BIT_COUNT работают только на INTEGER, и поэтому я бы сказал, что, вероятно, единственный способ сделать это - разбить двоичные строки в подстроках, отбросить каждую двоичную подстроку на integer, вычислите расстояние Хэмминга подстрокой, а затем добавьте их. Проблема в том, что это звучит ужасно сложно, неэффективно и определенно не изящно. Поэтому мой вопрос: можете ли вы предложить лучший способ? (обратите внимание, что я нахожусь на общем хостинге и поэтому не могу изменять сервер БД или загружать библиотеки)
Редактировать (1): Очевидно, что загрузка всей таблицы на PHP и выполнение вычислений там будет возможно, но я скорее избегайте этого, потому что эта таблица, вероятно, будет расти довольно большой.
редактировать (2): Сервер БД MySQL 5.1
редактировать (3): Мой ответ ниже содержит код, который я только что описал выше.
Редактировать (4): Я только узнал, что использование 4 BIGINT для хранения хэша вместо BINARY (32) дает значительные улучшения скорости (более чем в 100 раз быстрее). См. Комментарии к моему ответу ниже.
Не стесняйтесь также предложить различные способы хранения хэшей, если это может оказаться полезным в поиске лучшее решение. – CAFxX
Если вы сохранили хэш в 8 целых чисел (возможно, в дополнение к двоичному хранилищу), расчет становится намного проще. – Andomar
Мне очень интересно, почему вы хотели бы рассчитать расстояние :) – Nanne