Bonjour,
Ben..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) sous forme d'une fonction.
Alors:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
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.
Je comprends pas pourquoi ça fonctionne sur toute la liste mais plus sur le dernier mot du dico qui n'est pourtant pas accentué?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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)
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é.
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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)
Mais trop ardu ..et je voudrai comprendre.
Please Help me![]()
Partager