Dla porównania, tutaj jest bardziej zwięzła wersja:
def sha1OfFile(filepath):
import hashlib
with open(filepath, 'rb') as f:
return hashlib.sha1(f.read()).hexdigest()
Na drugim myśli: chociaż nigdy nie widziałem go, Myślę, że istnieje potencjał, aby f.read()
zwrócił mniej niż pełny plik lub plik o wielu gigabajtach, aby f.read() zabrakło pamięci. Dla każdego zbudowaniu, rozważmy, jak to naprawić: Pierwsza poprawka do tego jest:
def sha1OfFile(filepath):
import hashlib
sha = hashlib.sha1()
with open(filepath, 'rb') as f:
for line in f:
sha.update(line)
return sha.hexdigest()
Jednakże, nie ma gwarancji, że '\n'
pojawia się w pliku w ogóle, więc fakt, że pętla for
dadzą nam bloki pliku, który kończy się '\n'
może dać nam ten sam problem, który mieliśmy pierwotnie. Niestety, nie widzę podobnego Pythonowskiego sposobu na przerysowywanie bloków pliku tak dużych, jak to tylko możliwe, co, jak sądzę, oznacza, że utknęliśmy w pętli while True: ... break
i magiczną liczbą dla rozmiaru bloku:
def sha1OfFile(filepath):
import hashlib
sha = hashlib.sha1()
with open(filepath, 'rb') as f:
while True:
block = f.read(2**10) # Magic number: one-megabyte blocks.
if not block: break
sha.update(block)
return sha.hexdigest()
Oczywiście, kto powiedział, że możemy przechowywać ciągi jednomega megabajtowe. Prawdopodobnie możemy, ale co, jeśli jesteśmy na małym wbudowanym komputerze?
Żałuję, że nie mogę wymyślić czystszego sposobu, który gwarantuje, że nie zabraknie pamięci na ogromnych plikach i który nie ma liczb magicznych i który działa tak samo, jak oryginalne proste rozwiązanie Pythonic.
Nie można tak naprawdę zignorować różnicę, jeśli planujesz używać skrótów razem. –
Zapomniałem wspomnieć, po prostu użyłem gita jako wzorca, nie zamierzam ich używać razem. – Ikke
Jeśli plik może być dość duży, możesz przetworzyć go w bloku na raz, więc nie potrzebujesz całej rzeczy w pamięci RAM na raz: http://stackoverflow.com/questions/7829499/using-hashlib-to- compute-md5-digest-of-a-file-in-python3 – rakslice