16

ハミング距離で比較して取得するハッシュをmysqlに保存しています。

保存されるハッシュは次のとおりです。

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て使用するので問題ありませんbitcountvarbinaryここで、すでに格納されている文字/ハッシュmysqlが英数字であり、フィールドを変換するvarbinarybitcount、格納されたハッシュがバイナリ文字列ではないため機能しないという疑問が生じます。

私は何をすべきか?

私は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とfetchとの照合方法がわかりません。

4

1 に答える 1

8

例として最後の 2 つの数字を使用します。

SELECT BIT_COUNT( CAST(CONV('fffa181c1c3e3820', 16, 10) AS UNSIGNED) ^
                  CAST(CONV('fffa381c1c3e3828', 16, 10) AS UNSIGNED) ) ;
--> 2
  • ハッシュは 16 進数です。
  • 変換は で終了する必要がありBIGINT UNSIGNEDます。

(MD5 (128 ビット) または SHA1 (160 ビット) ハッシュがある場合はSUBSTR()、X または各ペア BIT_COUNT を介してそれらを分割し、結果を追加する必要がありました。)

列名を使用するように編集します。

SELECT BIT_COUNT( CAST(CONV( a.pagecontent , 16, 10) AS UNSIGNED) ^
                  CAST(CONV( b.pagecontent , 16, 10) AS UNSIGNED) ) ;
于 2015-06-23T15:47:09.100 に答える