Jak poprawić TypeError: Obiekty Unicode muszą zostać zakodowane przed mieszaniem?

295

Mam ten błąd:

Traceback (most recent call last):
  File "python_md5_cracker.py", line 27, in <module>
  m.update(line)
TypeError: Unicode-objects must be encoded before hashing

kiedy próbuję wykonać ten kod w Python 3.2.2 :

import hashlib, sys
m = hashlib.md5()
hash = ""
hash_file = input("What is the file name in which the hash resides?  ")
wordlist = input("What is your wordlist?  (Enter the file name)  ")
try:
  hashdocument = open(hash_file, "r")
except IOError:
  print("Invalid file.")
  raw_input()
  sys.exit()
else:
  hash = hashdocument.readline()
  hash = hash.replace("\n", "")

try:
  wordlistfile = open(wordlist, "r")
except IOError:
  print("Invalid file.")
  raw_input()
  sys.exit()
else:
  pass
for line in wordlistfile:
  # Flush the buffer (this caused a massive problem when placed 
  # at the beginning of the script, because the buffer kept getting
  # overwritten, thus comparing incorrect hashes)
  m = hashlib.md5()
  line = line.replace("\n", "")
  m.update(line)
  word_hash = m.hexdigest()
  if word_hash == hash:
    print("Collision! The word corresponding to the given hash is", line)
    input()
    sys.exit()

print("The hash given does not correspond to any supplied word in the wordlist.")
input()
sys.exit()
JohnnyFromBF
źródło
Odkryłem, że otwarcie pliku z „rb” pomogło mojej sprawie.
dlamblin

Odpowiedzi:

299

Prawdopodobnie szuka kodowania znaków z wordlistfile.

wordlistfile = open(wordlist,"r",encoding='utf-8')

Lub, jeśli pracujesz na zasadzie linia po linii:

line.encode('utf-8')
cwallenpoole
źródło
3
open(wordlist,"r",encoding='utf-8')dlaczego używać otwartego z określonym kodowaniem, kodowanie jest określane jako kodek dekodujący, bez tej opcji używa kodowania zależnego od platformy.
Tanky Woo,
129

Musisz zdefiniować encoding formatjak utf-8, spróbuj to łatwy sposób,

Ten przykład generuje liczbę losową przy użyciu algorytmu SHA256:

>>> import hashlib
>>> hashlib.sha256(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
'cd183a211ed2434eac4f31b317c573c50e6c24e3a28b82ddcb0bf8bedf387a9f'
Jay Patel
źródło
18

Aby zapisać hasło (PY3):

import hashlib, os
password_salt = os.urandom(32).hex()
password = '12345'

hash = hashlib.sha512()
hash.update(('%s%s' % (password_salt, password)).encode('utf-8'))
password_hash = hash.hexdigest()
Khắc Nghĩa Từ
źródło
1
Ta linia uniemożliwia użycie hasła. password_salt = os.urandom (32) .hex () Powinien mieć stałą znaną wartość, ale może być tajny tylko dla serwera. Popraw mnie lub dostosuj do swojego kodu.
Yash,
1
Zgadzam się z @Yash Masz albo jedną sól, którą używasz dla każdego skrótu (lub nie najlepszą), albo jeśli generujesz losową sól dla każdego skrótu, musisz przechowywać go z skrótem, aby użyć go później do porównania
Carson Evans
15

Błąd mówi już, co musisz zrobić. MD5 działa na bajtach, więc musisz zakodować ciąg Unicode bytes, np line.encode('utf-8'). Za pomocą .

Cat Plus Plus
źródło
11

Najpierw spójrz na to odpowiedź.

Teraz komunikat jest jasny: można używać tylko bajty, a nie ciągi Python (co było unicodew Pythonie <3), więc trzeba kodować sznurki z preferowanym kodowaniem: utf-32, utf-16,utf-8 a nawet jeden z ograniczona 8- kodowanie bitowe (co niektórzy nazywają stronami kodowymi).

Bajty w pliku listy słów są automatycznie dekodowane do formatu Unicode przez Python 3 podczas czytania z pliku. Proponuję zrobić:

m.update(line.encode(wordlistfile.encoding))

dzięki czemu zakodowane dane przekazywane do algorytmu md5 są kodowane dokładnie tak, jak plik leżący u podstaw.

tzot
źródło
10
import hashlib
string_to_hash = '123'
hash_object = hashlib.sha256(str(string_to_hash).encode('utf-8'))
print('Hash', hash_object.hexdigest())
Sabyasachi
źródło
6

Możesz otworzyć plik w trybie binarnym:

import hashlib

with open(hash_file) as file:
    control_hash = file.readline().rstrip("\n")

wordlistfile = open(wordlist, "rb")
# ...
for line in wordlistfile:
    if hashlib.md5(line.rstrip(b'\n\r')).hexdigest() == control_hash:
       # collision
jfs
źródło
6

kodowanie tej linii naprawiło to dla mnie.

m.update(line.encode('utf-8'))
Mike Cash
źródło
0

Jeśli jest to łańcuch jednowierszowy. owiń go za pomocą b lub B. np .:

variable = b"This is a variable"

lub

variable2 = B"This is also a variable"
SBimochan
źródło
-3

Ten program jest bezbłędną i ulepszoną wersją powyższego programu do krakowania MD5, który odczytuje plik zawierający listę zaszyfrowanych haseł i sprawdza je pod kątem zaszyfrowanych słów z listy słów w słowniku angielskim. Mam nadzieję, że to jest pomocne.

Pobrałem angielski słownik z następującego linku https://github.com/dwyl/english-words

# md5cracker.py
# English Dictionary https://github.com/dwyl/english-words 

import hashlib, sys

hash_file = 'exercise\hashed.txt'
wordlist = 'data_sets\english_dictionary\words.txt'

try:
    hashdocument = open(hash_file,'r')
except IOError:
    print('Invalid file.')
    sys.exit()
else:
    count = 0
    for hash in hashdocument:
        hash = hash.rstrip('\n')
        print(hash)
        i = 0
        with open(wordlist,'r') as wordlistfile:
            for word in wordlistfile:
                m = hashlib.md5()
                word = word.rstrip('\n')            
                m.update(word.encode('utf-8'))
                word_hash = m.hexdigest()
                if word_hash==hash:
                    print('The word, hash combination is ' + word + ',' + hash)
                    count += 1
                    break
                i += 1
        print('Itiration is ' + str(i))
    if count == 0:
        print('The hash given does not correspond to any supplied word in the wordlist.')
    else:
        print('Total passwords identified is: ' + str(count))
sys.exit()
udz
źródło