2015-06-20 23 views
15

Mam kilka skrótów przechowywanych w mysql, które chciałbym pobrać z porównania przez hamming distance.Mysql hamming odległość wartości heksadecymalnych

Hashe przechowywane są takie:

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 

normalnie pobrać jak:

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

Ale w mysql odległość Hamminga jest operatory bitowe, które można zrobić, jeśli struny były tylko numery:

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

Działa tylko w liczbie całkowitej (liczba), ale moim wymaganiem jest praca z liczbami i alfabetami, dla Przykład:

74898fababfbef46 and 95efabfeba752545 

Z mojego małego badań wiem, że najpierw muszę konwertować pole do binary a następnie użyć bitcount za pomocą CAST lub CONVERT jak:

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

lub

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

To jest w porządku jako konwersja danych do binary i użycie bitcount. Teraz powstaje pytanie, że znaki/hasze zapisane wsą już alfanumeryczne i jeśli skonwertuję pole na varbinary i bitcount, to nie zadziała, ponieważ zapisane skróty nie są ciągami binarnymi

Co należy zrobić?

byłem odnosząc jako php odległość Hamminga przykład dopasowującej:

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 

Ale ja nie rozumiejąc jak dopasować z mysql i sprowadzić, bo nie można wdrożyć go w mysql.

+0

Długość Hamminga działa na wartości binarne. Pierwsze dziewięć wartości wydaje się być 16 cyframi szesnastkowymi, łatwymi do interpretacji jako 64-bitowe wartości binarne. Wiemy, jak z tym pracować. Wtedy mówisz "działa tylko na liczbach całkowitych" ... to prawda, ponieważ możemy reprezentować 64-bitową wartość binarną jako BIGINT. Wtedy mówisz, że twoje wymaganie to "i alfabety" [sic], a ty pokazujesz wartości, które zawierają ** ''v'' ** i **' 'g'' **, a nie są to prawidłowe cyfry szesnastkowe. ** Co w plastiku? ** Zanim odpowiesz na twoje pytanie, musisz wyjaśnić, jaka wartość binarna ** '95gfgdgd75425456' ** ma reprezentować. – spencer7593

+0

Niestety nie zrozumiałeś pytania. W skrócie, mam hasze i tak, są one w postaci dziesiętnej szesnastkowej zapisanej w mysql.Teraz chcę porównać to z wysyłaniem, które można wykonać za pomocą bit_count, ale słyszałem, że działa tylko w liczbie całkowitej.Tak jeśli używam normalnie użyj jako SELECT pagedata, BIT_COUNT (pagecontent^'$ encrypted') searchengine WHERE pagecontent> 2; "), moją główną wątpliwość jest to praca alfanumeryczna czy nie? I to jest wątpliwość zmusiło mnie do zrobienia badań dla alternatywy bit_count.I dostaję to działa na integer tylko tutaj: http://stackoverflow.com/questions/4777070/hamming -distance-on-binary-string-in-sql? rq = 1 – 125fura

+0

Zrozumiałem pytanie, czego nie rozumiem, to jaka jest wartość binarna łańcuchów ** '74898acvdf566556' ** i **' 95gfgdgd7542545' ** powinien reprezentować. (Jest to szesnaście znaków, a większość znaków jest poprawnych cyfr szesnastkowych, ale znaki ** 'v' ** i **' g' ** są * nie * poprawnymi cyframi heksadecymalnymi). "Główna wątpliwość czy to działa alfanumerycznie, czy też nie" ... * Nie *, to nie działa.Liczba Hamminga działa na ** wartościach binarnych ** Łatwo jest przekonwertować szesnastkową reprezentację ciągów na binarne ... – spencer7593

Odpowiedz

6

Korzystanie dwie ostatnie cyfry jako przykład:

SELECT BIT_COUNT(CAST(CONV('fffa181c1c3e3820', 16, 10) AS UNSIGNED)^
        CAST(CONV('fffa381c1c3e3828', 16, 10) AS UNSIGNED)) ; 
--> 2 
  • mieszań są hex.
  • Konwersja musi zakończyć się na BIGINT UNSIGNED.

(Gdybyś miał MD5 (128-bit) lub SHA1 (160-bit) hashe, to musiałby podzielić je przez SUBSTR(), XOR każda para, BIT_COUNT, następnie dodać wyniki.)

Edytuj, aby użyć nazwy kolumny:

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

To ok, ale głównym pytaniem jest dopasowanie danych po stronie klienta do skrótów po stronie serwora, twoje rozwiązanie jest po stronie klienta (oznacza zmianę przed fecthig), ale co z już zapisanym i mysql, jak to zmienić? – 125fura

+0

@ 125fura: "jak to zmienić" (gdzie "to" odnosi się do wartości przechowywanych w kolumnie w tabeli MySQL), które zależy od ** typu danych ** kolumny oraz od tego, w jaki sposób wartości binarne są ** reprezentowany **. (Czy kolumny "CHAR (16)" zawierają szesnaście cyfr szesnastkowych, czy też kolumny zdefiniowane jako 'VARCHAR (21)' i zawierają ** '' qw 4 fffa181c3c2e3920'' **, jak pokazano w twoim pytaniu. d potrzeba użycia zależy od tego, w jaki sposób binarne wartości mieszania są reprezentowane w kolumnie.) – spencer7593

+0

Proszę podać 'SHOW CREATE TABLE'. –