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.
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
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 : 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)
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 : 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)
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