Tengo una tabla en mi base de datos donde almaceno hashes SHA256 en una columna BINARY (32). Estoy buscando una manera de calcular la distancia de Hamming de las entradas de la columna a un valor suministrado, es decir, algo así como:Distancia de Hamming en cadenas binarias en SQL
SELECT * FROM table
ORDER BY HAMMINGDISTANCE(hash, UNHEX(<insert supplied sha256 hash here>)) ASC
LIMIT 10
(en caso de que se esté preguntando, la distancia de Hamming de cadenas A y B se define como BIT_COUNT(A^B)
, donde^es el operador XOR bit a bit y BIT_COUNT devuelve el número de 1s en la cadena binaria).
Ahora, sé que tanto el operador^como la función BIT_COUNT solo funcionan en INTEGER, así que diría que probablemente la única forma de hacerlo sería dividir las cadenas binarias en subcadenas, convertir cada subcadena binaria en entero, calcule la distancia de Hamming en subcadena y luego agréguela. El problema con esto es que suena terriblemente complicado, no eficiente y definitivamente no elegante. Mi pregunta, por lo tanto, es: ¿podría sugerir alguna forma mejor? (tenga en cuenta que estoy en alojamiento compartido y por lo tanto no puedo modificar el servidor de base de datos o cargar bibliotecas)
editar (1): Obviamente, cargar toda la tabla en PHP y hacer los cálculos allí sería posible, pero yo preferiría evitarlo porque esta mesa probablemente crecerá bastante.
de edición (2): El servidor de base de datos es MySQL 5.1
edición (3): Mi respuesta a continuación contiene el código que he descrito anteriormente.
editar (4): Acabo de descubrir que usar 4 BIGINT para almacenar el hash en lugar de BINARY (32) produce mejoras de velocidad masivas (más de 100 veces más rápidas). Ver los comentarios a mi respuesta a continuación.
dude también para sugerir diferentes formas de almacenar los valores hash si esto podría ser útil en la búsqueda de una mejor solución. – CAFxX
Si almacena el hash en 8 enteros (quizás además del almacenamiento binario), el cálculo se vuelve mucho más fácil. – Andomar
Tengo mucha curiosidad por saber por qué querrías calcular la distancia :) – Nanne