web-dev-qa-db-fra.com

Hachage d'un fichier dans Python

Je veux que python lise le EOF afin que je puisse obtenir un hachage approprié, que ce soit sha1 ou md5. Aidez-moi. Voici ce que j'ai loin:

import hashlib

inputFile = raw_input("Enter the name of the file:")
openedFile = open(inputFile)
readFile = openedFile.read()

md5Hash = hashlib.md5(readFile)
md5Hashed = md5Hash.hexdigest()

sha1Hash = hashlib.sha1(readFile)
sha1Hashed = sha1Hash.hexdigest()

print "File Name: %s" % inputFile
print "MD5: %r" % md5Hashed
print "SHA1: %r" % sha1Hashed
62
user3358300

TL; DR utilise des tampons pour ne pas utiliser beaucoup de mémoire.

Je crois que nous arrivons au cœur de votre problème lorsque nous considérons les implications en termes de mémoire de travailler avec de très gros fichiers . Nous ne voulons pas que ce mauvais garçon passe à travers 2 Go de RAM pour un fichier de 2 gigaoctets alors, comme pasztorpisti fait remarquer, nous devons traiter ces gros fichiers en morceaux!

import sys
import hashlib

# BUF_SIZE is totally arbitrary, change for your app!
BUF_SIZE = 65536  # lets read stuff in 64kb chunks!

md5 = hashlib.md5()
sha1 = hashlib.sha1()

with open(sys.argv[1], 'rb') as f:
    while True:
        data = f.read(BUF_SIZE)
        if not data:
            break
        md5.update(data)
        sha1.update(data)

print("MD5: {0}".format(md5.hexdigest()))
print("SHA1: {0}".format(sha1.hexdigest()))

Ce que nous avons fait est de mettre à jour nos hachages de ce mauvais garçon en morceaux de 64 Ko à mesure que nous suivons le dandy pratique de hashlib méthode de mise à jour . De cette façon, nous utilisons beaucoup moins de mémoire que les 2 Go qu'il faudrait pour hacher le gars tout à la fois!

Vous pouvez tester cela avec:

$ mkfile 2g bigfile
$ python hashes.py bigfile
MD5: a981130cf2b7e09f4686dc273cf7187e
SHA1: 91d50642dd930e9542c39d36f0516d45f4e1af0d
$ md5 bigfile
MD5 (bigfile) = a981130cf2b7e09f4686dc273cf7187e
$ shasum bigfile
91d50642dd930e9542c39d36f0516d45f4e1af0d  bigfile

J'espère que ça t'as aidé!

De plus, tout cela est décrit dans la question liée à droite: Obtenir le hachage MD5 de gros fichiers en Python


Addenda!

En général, lorsque vous écrivez python, il est utile de prendre l'habitude de suivre pep-8 . Par exemple, dans python sont des variables Généralement, les caractères de soulignement sont séparés et non camelés. Mais c’est juste du style et personne ne se soucie vraiment de ces choses-là, à l’exception des personnes qui doivent lire de mauvais style ... ce qui pourrait bien être ce que vous lisez ce code dans quelques années.

100
Randall Hunt

Pour le calcul correct et efficace de la valeur de hachage d'un fichier (dans Python 3)):

  • Ouvrez le fichier en mode binaire (c’est-à-dire ajoutez 'b' Au mode de fichier) pour éviter les problèmes d’encodage des caractères et de conversion de fin de ligne.
  • Ne lisez pas le fichier complet en mémoire, car c'est un gaspillage de mémoire. Au lieu de cela, lisez-le séquentiellement bloc par bloc et mettez à jour le hachage pour chaque bloc.
  • Éliminez la double mise en tampon, c’est-à-dire n’utilisez pas d’IO-tamponnées, car nous utilisons déjà une taille de bloc optimale.
  • Utilisez readinto() pour éviter le retournement de la mémoire tampon.

Exemple:

import hashlib

def sha256sum(filename):
    h  = hashlib.sha256()
    b  = bytearray(128*1024)
    mv = memoryview(b)
    with open(filename, 'rb', buffering=0) as f:
        for n in iter(lambda : f.readinto(mv), 0):
            h.update(mv[:n])
    return h.hexdigest()
35
maxschlepzig

Ouvrez le fichier en mode binaire, le mode par défaut de open() est 'r' qui est "ouvert à la lecture en mode texte". En mode texte, la conversion de nouvelle ligne est effectuée sur vos données. Cela peut également causer des bogues spécifiques à la plate-forme, mais un problème possible pouvant résulter du mode texte est que les séquences "\ r\n" sont remplacées par des séquences "\ n" dans le répertoire. chaîne que vous obtenez à vos mains. Tous les fichiers ne contiennent pas de séquences "\ r\n", en particulier dans le cas de fichiers binaires, le bogue ne viendrait donc pas tout le temps et il serait difficile de le détecter.

openedFile = open(inputFile, 'rb')

Il y a un autre petit problème ici. Vous lisez le fichier en gros morceaux. En le lisant par petits morceaux de quelques kilo-octets, vous pouvez hacher des fichiers très volumineux même s’ils ne rentrent pas dans votre mémoire disponible.

6
pasztorpisti

Je proposerais simplement:

def get_digest(file_path):
    h = hashlib.sha256()

    with open(file_path, 'rb') as file:
        while True:
            # Reading is buffered, so we can read smaller chunks.
            chunk = file.read(h.block_size)
            if not chunk:
                break
            h.update(chunk)

    return h.hexdigest()

Toutes les autres réponses ici semblent trop compliquer. Python est déjà en mémoire tampon lors de la lecture (de manière idéale, ou vous configurez cette mémoire tampon si vous avez plus d'informations sur le stockage sous-jacent) et il est donc préférable de lire en morceaux la fonction de hachage trouve ce qui est idéal. Pour calculer la fonction de hachage plus rapidement ou au moins moins beaucoup de temps en ressources de calcul, utilisez plutôt Python) et contrôlez ce que vous devez contrôler: ce que le consommateur doit contrôler. de vos données trouve idéal, taille de bloc de hachage.

3
Mitar

J'ai programmé un module capable de hacher de gros fichiers avec différents algorithmes.

pip3 install py_essentials

Utilisez le module comme ceci:

from py_essentials import hashing as hs
hash = hs.fileChecksum("path/to/the/file.txt", "sha256")
2
phyyyl
import hashlib
user = input("Enter ")
h = hashlib.md5(user.encode())
h2 = h.hexdigest()
with open("encrypted.txt","w") as e:
    print(h2,file=e)


with open("encrypted.txt","r") as e:
    p = e.readline().strip()
    print(p)
2
Ome Mishra