Uncle Den's Uncle Den's

Code de Vigénère

Le principe du code de Vigénére est basé sur une clé de cryptage. Pour l'exemple, je choisis pour mot SECRET
Texte en clair
A
U
J
O
U
R
D
H
U
I
...
+ Clé de cryptage
S
E C
R
E
T
S
E
C
R
...
= Texte crypté
S
Y
L
F
Y
K
V
L
W
Z
...

Avec A=0, B=1...
A+S=S
U+E=Y
...

source=open(u'etranger04_sans_espace.txt',"r")

cle="secret"
longcle=len(cle)
print(longcle)
offset=97

decal=[0]*longcle
for i in range (longcle):
    decal[i]=ord(cle[i])-offset
   
txt=""
texte=source.read()
texte=texte.lower()
longtxt=len(texte)

print(longtxt)

for i in range(longtxt):
    lettre=texte[i]
    code=offset+((ord(lettre)-offset+decal[i%longcle])%26)
    txt+=chr(code)
    # on aurait pu ecrire directement:
    # txt+=chr(offset+((ord(texte[i])-offset+decal[i%longcle])%26))
   
destination = open("etranger_code_vigenere.txt", "w")
destination.write(txt)
destination.close()
source.close()


Pour le décodage, la disfficulté est d'abord de connaitre la longueur de la clé, et ensuite trouver la clé.
Il existe plusieurs méthodes dont celle ci que nous n'appliquons pas ici.

La méthode que nous utilisons ici est de tester différentes longueurs de clé, de calculer pour chaque rang de décalage imposé par la clé de cryptage un histogramme. Cet histogramme est comparé à l'histogramme "français" : on cherche à minimiser  la difference entre les 2 histogrammes ce qui détermine le décalage potentiel pour chaque lettre de la clé.

césar décallage
(image reprise de  http://michel.caron.pagesperso-orange.fr/algorithme/decryptage.html)


source=open(u'etranger_code_vigenere.txt',"r")
txt=""
i=0
texte=source.read()
texte=texte.lower()
offset=97
longtxt=len(texte)
print(longtxt)

car=(("a",9.738),
    ("b",0.721),
    ("c",2.880),
    ("d",3.417),
    ("e",16.85),
    ("f",0.800),
    ("g",0.772),
    ("h",0.671),
    ("i",8.221),
    ("j",1.331),
    ("k",0.004),
    ("l",5.494),
    ("m",3.685),
    ("n",6.336),
    ("o",4.946),
    ("p",2.644),
    ("q",1.322),
    ("r",6.190),
    ("s",7.763),
    ("t",7.172),
    ("u",6.532),
    ("v",1.796),
    ("w",0.005),
    ("x",0.310),
    ("y",0.276),
    ("z",0.109))


l=len(car)
print(l)
nb=[0]*l

longmaxcle=10 # On  teste des longueurs de clés inférieures à 10 caractères

txtrang=[""]*longmaxcle

for longcle in range(2,longmaxcle,1):
    cle=""
    for rang in range (0,longcle):
        txtrang[rang]=""
        for k in range(rang,longtxt,longcle):
            txtrang[rang]+=texte[k]
           

        maxi=1.0
        somme=0.0

        for i in range(l):
            nb[i]=txtrang[rang].count(car[i][0])
            somme+=nb[i]
            if maxi<nb[i]:
                maxi=nb[i]
        #print("")       
        for i in range(l):
            # print(str(i)+" "+car[i][0]+" "+str(nb[i])+" / "+str(maxi)+" / "+str(somme))
            #print(car[i][0]+" "+int(50*nb[i]/maxi)*"=")
            8
        #print("")
        for i in range(l):
            nb[i]=100.0*nb[i]/somme
            # print("long cle = "+str(longcle)+" / Rang = "+str(l-rang)+" / "+car[i][0]+" : "+str(nb[i])[0:5]+" %")
        #print("")
        mini=1000000
        rg=0
        for off in range (l):
            delta=0

            for i in range (l):
                delta+=(nb[(i-off)%l]-car[i][1])**2 # on calcule l'écart entre les histogrammes, il faut cque cet écart soit minimum
           
            if delta<mini:
                mini=delta
                rg=off
        cle+=chr(((-rg)%l)+offset)
    print("long cle = "+str(longcle)+" / Rang = "+str(l-rang)+" / cle = "+cle+" : delta = "+str(delta)[0:3]+" / rang = "+str(rg))
source.close()


Une fois la longueur de clé et la clé potentiellement trouvée, on teste le décodage du texte codé:

fichier="etranger"
source=open(u'etranger_code_vigenere.txt',"r") #enregistrer le fichier en ANSI avec le blocnote)

cle="secret"
longcle=len(cle)
print(longcle)
offset=97

decal=[0]*longcle
for i in range (longcle):
    decal[i]=ord(cle[i])-offset
   
txt=""
texte=source.read()
texte=texte.lower()

longtxt=len(texte)

print(longtxt)

for i in range(longtxt):
    lettre=texte[i]
    code=offset+((ord(lettre)-offset-decal[i%longcle])%26)
    txt+=chr(code)
    # on aurait pu ecrire directement:
    # txt+=chr(offset+((ord(texte[i])-offset+decal[i%longcle])%26))
   
destination = open(fichier+"_dec.txt", "w")
destination.write(txt)
destination.close()
source.close()

>> Cacher une image dans une autre
<< retour accueil cryptographie et Python