Ab und an kommt man in die Verlegenheit, zwei Werte bitwise xor vergleichen und den Unterschied in Prozent ermitteln zu müssen.

Hier ein paar einfache Beispiele, wie man zwei Hashwerte miteinander vergleichen kann. Nebenbei will Ich will mir ein Code Template zusammenstellen.

Fangen wir mit der MYSQL Query an.

  1. SELECT ((64 - bit_count(nNumber ^ nNumber))*100.0/64);

    SELECT ((64 - bit_count(111 ^ 110))*100.0/64);
    +----------------------------------------+
    | 98.43750
    +----------------------------------------+
    Ergibt also eine 98,44 prozentige Ähnlichkeit zwischen diesen Werten. Farbwerte vergleichen wäre eine Möglichkeit.

  2. Als MYSQL Funktion

    1. DELIMITER $$
    2. DROP FUNCTION IF EXISTS compare $$
    3. CREATE FUNCTION compare (hash1 bigint, hash2 bigint)
    4. RETURNS float
    5. DETERMINISTIC
    6. BEGIN
    7. RETURN ((64 - bit_count(hash1 ^ hash2))*100.0/64);
    8. END $$
    9. DELIMITER ;



Das war jetzt nicht besonders kompliziert. Nur sind Big Integer in MYSQL stark limitiert. Wir brauchen also was weitergehendes, wenn wir zwei lange Hashwerte miteinander vergleichen wollen.

Typisches Anwendungsbeispiel wäre die Ähnlichkeit zweier Bilder herauszufinden, sofern man für diese bereits einen Hashwert ermittelt hat. Hierfür gibt es diverse Algorithmen, auf die ich später noch eingehen werde. Wobei sich hier, bei großen Datenbanken, ein MYSQL library plugin anbieten würde.

BITWISE XOR - HAMMING DISTANCE

  1. DELIMITER $$
  2. DROP FUNCTION IF EXISTS comparehash $$
  3. CREATE FUNCTION comparehash (hash1 varchar(256), hash2 varchar(256), maxlen int)
  4. RETURNS float
  5. DETERMINISTIC
  6. BEGIN
  7. DECLARE hashpart1 varchar(64) DEFAULT "";
  8. DECLARE hashpart2 varchar(64) DEFAULT "";
  9. DECLARE bitcnt int DEFAULT 0;
  10. DECLARE strlen int DEFAULT 16;
  11. DECLARE i int DEFAULT 0;
  12. DECLARE len int DEFAULT 0;
  13. SET len = LENGTH(hash1) / strlen;
  14. WHILE i<len AND i < maxlen DO
  15. SET hashpart1 = SUBSTRING(hash1,(i*strlen)+1,strlen);
  16. SET hashpart2 = SUBSTRING(hash2,(i*strlen)+1,strlen);
  17. SET bitcnt = bitcnt + bit_count(cast(conv(hashpart1, 16, 10) as unsigned) ^ cast(conv(hashpart2, 16, 10) as unsigned));
  18. SET i = i+1;
  19. END WHILE;
  20. RETURN ((64*i)-bitcnt)*100.0/(64*i);
  21. END $$
  22. DELIMITER ;


SELECT comparehash('ffffff00', 'eeeeee00', 1) as percent;
96.875 = ergibt eine 96,88 prozentige Ähnlichkeit zwischen diesen beiden Werten.

Die Strings müssen mindestens 8 Zeichen lang sein. Der Parameter maxlen gibt an, wieviele Blöcke der Hashwerte miteinander verglichen werden sollen. Falls man sehr lange Hashwerte hat, kann man hier (aus Performancegründen) den Vergleich einschränken.

Vielleicht ganz nützlich, wenn man zwei Hashwerte miteinander vergleichen will und den Unterschied in Prozent ermitteln möchte.

Code Template passt noch nicht. Werde mir da eine andere Lösung einfallen lassen.

teile diesen Beitrag

0 Kommentare

Diskutiere mit!

 
Kommentar senden