2015-06-20 1 views
15

У меня есть хеши, хранящиеся в mysql, которые я бы получил при сравнении расстоянием от хамминга.Mysql hamming distance of hexadecimal values ​​

хэши хранятся следующие:

qw 1 ffe71b001820a1fd 
qw 2 ffffb81c1c3838a0 
qw 3 fff8381c1c3e3828 
qw 4 fffa181c3c2e3920 
qw 5 fffa981c1c3e2820 
qw 6 ff5f1c38387c1c04 
qw 7 fff1e0c1c38387ef 
qw 8 fffa181c1c3e3820 
qw 9 fffa381c1c3e3828 

Я обычно получать как:

SELECT product_id, HAMMING_DISTANCE(phash, 'phashfromuserinput') ; 

Но в MySQL Хэмминга расстояние побитовое оператор, который я могу сделать, если строки были только цифры:

SELECT pagedata,BIT_COUNT(pagecontent^'$encrypted')searchengine WHERE pagecontent > 2 ; ") 

Он работает только в целочисленном (число), но мое требование - работа с числами и алфавитами, для Пример:

74898fababfbef46 and 95efabfeba752545 

Из моего небольшого исследования я знаю, что сначала я должен преобразовать поле в binary, а затем использовать bitcount с помощью CAST или CONVERT как:

SELECT BIT_COUNT(CONV(hash, 2, 10)^
0b0000000101100111111100011110000011100000111100011011111110011011) 

или

SELECT BIT_COUNT(CAST(hash AS BINARY)) FROM data; 

Это нормально, как преобразование данных в binary и с использованием bitcount. Теперь возникает вопрос, что varbinary символов/хешей, хранящихся в mysql, уже являются буквенно-цифровыми, и если я конвертирую поле в varbinary и bitcount, то это не сработает, поскольку хранимые хэши не являются двоичными строками.

Что мне делать?

я ссылаюсь, как PHP расстояние Хэмминга согласующего пример:

function HammingDistance($bin1, $bin2) { 
    $a1 = str_split($bin1); 
    $a2 = str_split($bin2); 
    $dh = 0; 
    for ($i = 0; $i < count($a1); $i++) 
     if($a1[$i] != $a2[$i]) $dh++; 
    return $dh; 
} 

echo HammingDistance('10101010','01010101'); //returns 8 

Но я не понимая, как в соответствии с MySQL и принести, потому что я не могу реализовать его в MySQL.

+0

расстояние Хэмминга работает на двоичных значений. Первые девять значений выглядят как 16 шестнадцатеричных цифр, которые легко интерпретировать как 64-битные двоичные значения. Мы знаем, как с этим работать. Затем вы говорите: «работает только в целочисленном» ... это своего рода истина, поскольку мы можем представлять 64-битное двоичное значение как BIGINT. Затем вы говорите, что ваше требование «и алфавиты» [sic], и вы показываете значения, которые содержат ** '' v'' ** и ** '' g'' **, и это не действительные шестнадцатеричные цифры. ** Что в пластике? ** Прежде чем ответить на ваш вопрос, вам нужно объяснить, что должно представлять двоичное значение ** '95gfgdgd75425456' **. – spencer7593

+0

Извините, у меня не было вопросов. Короче говоря, у меня есть хэши и да, они шестнадцатеричные десятичные, хранящиеся в mysql. Просто хочу сравнить это с отправкой i, что можно сделать с помощью bit_count, но я слышал, что он работает только в integer.So, если я обычно использую как SELECT pagedata, BIT_COUNT (pagecontent^'$ encrypted') searchengine WHERE pagecontent> 2; «), мое главное сомнение в том, что это работа в алфавитно-цифровом или нет? Я сомневаюсь, что я сделал исследование для альтернативы bit_count.I получить его работу в целочисленном только отсюда: http://stackoverflow.com/questions/4777070/hamming -distance-on-binary-strings-in-sql? rq = 1 – 125fura

+0

Я понял вопрос. Что я не понимаю, это то, что двоичное значение строки ** '74898acvdf566556' ** и **' 95gfgdgd7542545' ** являются (это шесть символов, и большинство символов являются шестыми цифрами, но символы ** 'v' ** и **' g' ** являются * не * действительными шестнадцатеричными цифрами.) Что касается вашего «Главное сомнение - это работа в алфавитно-цифровом или нет» ... * Нет *, это не работает. Расстояние Хэмминга работает на ** двоичных ** значениях. Легко преобразовать шестнадцатеричное строковое представление в двоичное ... – spencer7593

ответ

6

Используя последние две цифры в качестве примера:

SELECT BIT_COUNT(CAST(CONV('fffa181c1c3e3820', 16, 10) AS UNSIGNED)^
        CAST(CONV('fffa381c1c3e3828', 16, 10) AS UNSIGNED)) ; 
--> 2 
  • хешей шестигранный.
  • Конвертация должна быть завершена BIGINT UNSIGNED.

(Если вы имели MD5 (128-бит) или SHA1 (160-бит) хэши, мы должны были бы разделить их с помощью SUBSTR(), Xor каждая пара, BIT_COUNT, затем добавили результаты.)

Редактировать, чтобы использовать имя столбца:

SELECT BIT_COUNT(CAST(CONV(a.pagecontent , 16, 10) AS UNSIGNED)^
        CAST(CONV(b.pagecontent , 16, 10) AS UNSIGNED)) ; 
+0

Это нормально, но главный вопрос заключается в сопоставлении данных на стороне клиента с хешами сторон сервера, ваше решение для клиентской стороны (означает изменение перед fecthig), но как насчет уже сохраненного i mysql, как его изменить? – 125fura

+0

@ 125fura: «как изменить это» (где «that» относится к значениям, которые хранятся в столбце в таблице MySQL), которые зависят от типа ** ** типа столбца и как двоичные значения ** представлены **. (Являются столбцами 'CHAR (16)', содержащими шестнадцать шестнадцатеричных цифр, или являются столбцами, определенными 'VARCHAR (21)' и содержат ** '' qw 4 fffa181c3c2e3920'' **, как показано в вашем вопросе. d необходимо использовать, зависит от того, как бинарные значения хеши будут представлены в столбце. – spencer7593

+0

Пожалуйста, предоставьте 'SHOW CREATE TABLE'. –