2015-08-03 1 views
2

Considérons le code ci-dessous. Il convertit une image en dessin au trait puis calcule le md5sum des bits. Je ne connais pas mieux de faire cela qu'avec une expression génératrice produisant des bits individuels. Mais alors comment puis-je nourrir le résultat de MD5 de manière efficace?Comment calculer efficacement la somme md5 d'un itérable de bits en Python?

Le code ci-dessous il ne avec un objet bitarray, mais j'obtenir des résultats non-déterministe distribuant bitarray instances (qui semblent utiliser des trucs de fantaisie C sous le capot) à md5. Alors, quelle est la "bonne" façon de faire cela?

import os, hashlib 
from PIL import Image 
from bitarray import bitarray 

def image_pixel_hash_code(image): 
    pixels = list(image.getdata()) 
    avg = sum(pixels)/len(pixels) 
    bits = bitarray(pixel < avg for pixel in pixels) 
    return hashlib.md5(bits).hexdigest() 


im = Image.open(os.path.expanduser("~/Downloads/test.jpg")).convert("L") 
print image_pixel_hash_code(im) 

P.S. Je peux reproduire le non-déterminisme bitarray mais je suppose que c'est juste une fonction d'utiliser deux choses ensemble qui ne sont pas censées fonctionner ensemble.

+0

tant que l'interface d'une chose à l'autre se fait correctement, il n'y a aucune raison qu'ils ne fonctionnent pas ensemble. 'bitarray' ne produit pas de résultats non déterministes, cela serait inutile si c'était le cas. BTW, vous pourriez simplifier un peu les choses avec 'bits = bitarray (pixel martineau

+0

@martineau, j'ai amélioré votre code, merci. Et John a résolu le mystère du non-déterminisme (j'avais besoin de zéros). – kuzzooroo

Répondre

3

Le hachage est notamment bits aléatoires à la fin de bits si la longueur de bits n'est pas un multiple de 8.

Vous pouvez le voir en regardant memoryview(bits)

Vous pouvez corriger ce problème en rembourrage bits avec 0 s

bits = bitarray(1 if pixel < avg else 0 for pixel in pixels) 
    bits.fill() 
    return hashlib.md5(bits).hexdigest() 
+0

Merci! J'apprécie particulièrement les pointeurs sur 'memoryview' et' fill'. Aurais-je raison de déduire que maintenant que Bitarray se comporte cette approche est raisonnablement efficace? – kuzzooroo

+0

kuzzooroo: Il est difficile de dire si c'est "efficace". Il calcule le md5 en additionnant moins de valeurs, mais nécessite une bonne quantité de traitement pour les produire. Seul le timing détermine si c'est plus rapide qu'une alternative. Il convient de noter qu'un effet secondaire majeur de l'utilisation de cette méthode est qu'elle est moins susceptible de détecter les différences d'image que l'application de md5 à toutes les données brutes de l'image - si c'est ce que vous utilisez. – martineau