Python Débutant: Erreur encodage Latin-1 vs utf-8 lecture des mots d'un dico dans un fonction..
Bonjour,
Ben.. :calim2: j'ai fais mon possible pour essayer d'y arriver seul.
Mais j'ai besoin d'aide. Je tourne en rond.mais d'une force!!
j'ai lu des sujets, posts, blogs sur les erreurs codage/décodage, latin-1 et utf-8, ASCII et autre unicode, bytes et BOM.. bref trop dur pour mon faible niveau pour trouver et comprendre comment corriger cet "étrange comportement" de ce programme.
Voici la situation:
Mon IDE (pour pyton 3.8) c'est Pyzo 4.9.0.
Je suis sous windows 10.
j'essai de faire un petit prog proposé dans ce bouquin: https://automatetheboringstuff.com/chapter13/
Les fichiers, (dictionnary.txt et meetingminutes.pdf en l'occurrence) sont dans l'archive téléchargeable ici : https://nostarch.com/download/Automa...ematerials.zip
Le programme doit retrouver le mot de passe d'un pdf (préalablement crypté avec ce mot de passe) en soumettant un à un les mots d'un dico (dictionary.txt) à la fonction decrypt() du pdf, puis afficher le mot si cette fonction retourne 1 / True.
J'ai bricolé ça (merci de votre indulgence :oops:) sous forme d'une fonction.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import PyPDF2 # importe le module pdf
def pdfDicoSearchPW(pdfName):
pdfFileObj = open(pdfName, 'rb') # ouvrir le pdf en lecture binaire
pdfReader = PyPDF2.PdfFileReader(pdfFileObj) # creation d'un objet reader
if pdfReader.isEncrypted==True: # si le pdf est crypté
dictionnaire="dictionary.txt" #dictionnaire anglais majuscules
with open(dictionnaire, "r", encoding='utf-8') as file:
data = file.read() # placer le contenu de la lecture du dico dans data
for each in data.split(): # pour chaque mot du texte splité.
if pdfReader.decrypt(each)==True: # si c'est 1 (True)
return each # retourne le mot trouvé dans le dico et arrete le prog |
Alors:
Pour le "dictionary.txt" (UTF-8 écrit en bas à droite de note pad), structuré avec des mots anglais en majuscule allant de:
AARHUS
AARON
..
..
ZULUS
ZURICH
Si je teste un pdf crypté par mot de passe ABBY, COULD, KNOX, SEND, etc.. ça fonctionne..
Si je teste avec un pdf crypté par l'avant dernier mot ZULUS ça fonctionne encore..
Par contre, quand je teste avec un pdf crypté par mot de passe ZURICH (dernier mot du dico), dès le lancement du programme, apparaît ce message d'erreur.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
>>> pdfDicoSearchPW('Encrypted-ZURICH.pdf')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\Gillian\Desktop\Informatique\Programmation\Python\JmaWorkSpace\PublieDeveloppez-PdfBrutForceDico.py", line 16, in pdfDicoSearchPW
if pdfReader.decrypt(each)==True: # si c'est 1 (True)
File "c:\users\gillian\appdata\local\programs\python\python38-32\lib\site-packages\PyPDF2\pdf.py", line 1987, in decrypt
return self._decrypt(password)
File "c:\users\gillian\appdata\local\programs\python\python38-32\lib\site-packages\PyPDF2\pdf.py", line 2017, in _decrypt
val = utils.RC4_encrypt(new_key, val)
File "c:\users\gillian\appdata\local\programs\python\python38-32\lib\site-packages\PyPDF2\utils.py", line 181, in RC4_encrypt
retval += b_(chr(ord_(plaintext[x]) ^ t))
File "c:\users\gillian\appdata\local\programs\python\python38-32\lib\site-packages\PyPDF2\utils.py", line 238, in b_
r = s.encode('latin-1')
UnicodeEncodeError: 'latin-1' codec can't encode character '\u20b7' in position 0: ordinal not in range(256) |
Je comprends pas pourquoi ça fonctionne sur toute la liste mais plus sur le dernier mot du dico qui n'est pourtant pas accentué?
Note:----------
Par ailleurs, j'ai testé un autre "Dico-FR-minuscule.txt" français (écrit en minuscules avec accents et en UTF-8 (vu sur notepad)).
aaron
abaissé
abaissement
..
Hélène
..
Zurich
zygote
Avec un fichier pdf crypté par mot de passe Hélène.
Le programme se lance, cherche une minute... et d'un coup renvoie ce même type de message d'erreur sans avoir trouvé.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
>>> pdfDicoSearchPW('Encrypted-Hélène.pdf')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\Gillian\Desktop\Informatique\Programmation\Python\JmaWorkSpace\PublieDeveloppez-PdfBrutForceDico.py", line 16, in pdfDicoSearchPW
if pdfReader.decrypt(each)==True: # si c'est 1 (True)
File "c:\users\gillian\appdata\local\programs\python\python38-32\lib\site-packages\PyPDF2\pdf.py", line 1987, in decrypt
return self._decrypt(password)
File "c:\users\gillian\appdata\local\programs\python\python38-32\lib\site-packages\PyPDF2\pdf.py", line 1997, in _decrypt
user_password, key = self._authenticateUserPassword(password)
File "c:\users\gillian\appdata\local\programs\python\python38-32\lib\site-packages\PyPDF2\pdf.py", line 2036, in _authenticateUserPassword
U, key = _alg35(password, rev,
File "c:\users\gillian\appdata\local\programs\python\python38-32\lib\site-packages\PyPDF2\pdf.py", line 2973, in _alg35
key = _alg32(password, rev, keylen, owner_entry, p_entry, id1_entry)
File "c:\users\gillian\appdata\local\programs\python\python38-32\lib\site-packages\PyPDF2\pdf.py", line 2866, in _alg32
password = b_((str_(password) + str_(_encryption_padding))[:32])
File "c:\users\gillian\appdata\local\programs\python\python38-32\lib\site-packages\PyPDF2\utils.py", line 238, in b_
r = s.encode('latin-1')
UnicodeEncodeError: 'latin-1' codec can't encode character '\u0153' in position 7: ordinal not in range(256) |
J'en déduis qu'il y a des erreurs d'encodage/décodage entre latin-1 et utf-8 sur certain mots de ces dictionnaires et/ou dans mon code.
Mais trop ardu ..et je voudrai comprendre.
Please Help me :)