-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
191 lines (152 loc) · 5.83 KB
/
utils.py
File metadata and controls
191 lines (152 loc) · 5.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
import math
import re
import string
from pathlib import Path
from typing import Any, Dict, List, TypedDict
class StatsDict(TypedDict):
imprimable: float
nombre_mots: int
p_mots_valide: float
non_mots: List[str]
ponctuation_valide: int
def calculer_entropie(bytes: bytes) -> float:
'''
Calcul l'entropie (le désordre dans une suite de données) afin de déterminer le degré d'improbabilité d'une chaine de données.
Args:
bytes(bytes): La donnée brute contenue dans le fichier crypté.
Returns:
float: l'entropie calculée.
'''
entropie = 0
proba_byte = 0
for specifique_byte in bytes:
i = 1
for chaque_byte in bytes:
if(chaque_byte == specifique_byte):
i += 1
proba_byte = 1 / i
entropie += (proba_byte) * math.log(1/proba_byte, 8)
return entropie
def est_dechiffre(texte:str) -> bool:
"""
Détermine si oui ou non une chaine a été déchiffrée
Args:
texte(str): la chaine en supposée déchiffrée
Returns:
bool: déchiffrée ou non
"""
stats:dict[str, Any] = verifier_texte_dechiffre(texte)
pourcent=0
# Les caractères imprimables constituent 50% de la validation du déchiffrement
if stats['imprimable'] > 70 :
pourcent += 50
# Le pourcentage de mots validés par les dictionnaires en constitue 30%
if stats['p_mots_valide'] > 50 :
pourcent += 30
# Le respect de la ponctuation, les 20% restants
if stats['ponctuation_valide'] > 50 :
pourcent += 20
return True if pourcent > 80 else False
def verifier_texte_dechiffre(texte: str) -> Dict[str, Any]:
"""
Verifie que le dechiffrement d'un message a bien été effectué sur la base de certains critères.
Args:
texte(str): Le texte supposé déchiffré.
Returns:
JSON(dictionnaire): statistiques sur le texte soit
-le pourcentage de caratères imprimables,
-le nombre de mots,
-le pourcentage de mots valide,
-les mots non valides et
-le pourcentage de ponctuation respecté
"""
#Statistiques sur le texte
stats: dict[str, Any] = {
'imprimable':0,
'nombre_mots':0,
'p_mots_valide':0,
'non_mots':[],
'ponctuation_valide':0
}
if not texte:
return stats
#Verifier le pourcentage de caractères imprimables.
stats['imprimable'] = int(sum(1 for char in texte if char.isprintable()) / len(texte) * 100)
# Traitement du texte brut pour obtenir une séquence distincte de pseudo-mot à cette étape séparé par des espaces
tab='./:!\\}{_%*$£&#;,~"()[]=§|`^@?'
copy=texte
for lettre in tab:
copy=copy.replace(lettre, ' ')
mots = [mot.removesuffix('\n').removeprefix('\n') for mot in copy.strip().split(' ') if mot != '\n']
stats['nombre_mots']=len(mots)
# Verifier que le chaque mot du texte est un mot anglais/francais
try:
mots_valides = 0
for mot in mots:
trouve=False
if not mot: continue
first_char = mot[0].lower()
for syl in ['Fr', 'En']:
chemin = Path(f"dico{syl}")/f"{first_char}.txt"
try:
with open(chemin, 'r', encoding='latin-1') as f:
for ligne in f:
if re.match(ligne.strip().removesuffix('\n'), mot, re.I):
mots_valides += 1
trouve=True
break
except FileNotFoundError:
continue
if trouve : break
if not trouve :
stats['non_mots'].append(mot)
if mots:
stats['p_mots_valide'] = round((mots_valides / len(mots)) * 100, 2)
else:
stats['p_mots_valide'] = 0.0
except Exception:
raise
#Verifier la structure de ponctuation.
points='.?!;,'
count = 0
nbr_points = 0
for i, char in enumerate(texte):
if char in points:
nbr_points += 1
if (i == len(texte) - 1) or (texte[i+1] == ' '):
count += 1
if not nbr_points: nbr_points=1
stats['ponctuation_valide'] = round(count*100/nbr_points, 2)
return stats
def rangerDico() -> None:
"""
Fonction utilitaire de rangement du dictionnaire anglais téléchargé
Pour effectuer des tests
"""
i=0
compte = 0
# Ouverture du grand dictionnaire.
try :
# Utilisation de Path pour un chemin portable
words_path = Path.cwd() / "words_alpha.txt"
with open(words_path,'r') as f:
while i<26:
# Définition du chemin vers le fichier de chaque mot en fonction de l'alphabet.
dico_path = Path.cwd() / "dicoEn" / f"{string.ascii_lowercase[i]}.txt"
with open(dico_path, 'a') as fichier:
#Ecriture dans le fichier.
fichier.write(string.ascii_lowercase[i]+'\n')
while 1 :
ligne=f.readline()
if ligne.startswith(string.ascii_lowercase[i]) or ligne.startswith('y'):
fichier.write(ligne)
compte += 1
else :
break
# Fermeture du fichier apres écriture du dernier mot.
fichier.close()
i+=1
print(compte)
except FileNotFoundError:
print('Fichier non trouvé.')
# rangerDico()