2015-05-22 09:00:44 +00:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
2015-05-22 09:52:11 +00:00
# fonction qui calcule le nombre de rotors en fonction de la clé pKey et qui retourne un entier
def calcLevel ( pKey , pSIGMA ) :
xN = 0 ;
for r in range ( 1 , 100 ) :
if ( pKey > = len ( pSIGMA ) * * r ) : # si la clé est inférieure à la valeur max pour r rotors
xN = r ; # on enregistre la valeur
else : # sinon (c'est qu'on a dépassé)
break ; # on arrête la boucle et on renvoie la derniere valeur de r (xN)
return xN ;
2015-05-21 18:45:08 +00:00
# fonction qui retourne une liste de nombres entre 0 pLength a partir d'un nombre
# compris entre 0 et pLength**pLevel
def decomposeKey ( pNum , pLength , pLevel ) :
xReturn = [ ] ;
n = pNum
for i in range ( pLevel - 1 , - 1 , - 1 ) :
xReturn . append ( n / / ( pLength * * i ) ) ;
n - = xReturn [ i - pLevel + 1 ] * ( pLength * * i )
return xReturn ;
# fonction qui melange une liste pSIGMA melangee par une cle pKEY
def shuffle ( pSIGMA , pKEY ) :
xReturn = [ ]
pList = pSIGMA [ : ]
l = len ( pList )
i = pKEY % l ; # rang actuel
n = 0 ; # nombre d'elements traites
while ( n < len ( pList ) ) :
2015-05-22 08:33:54 +00:00
if ( pList [ i ] != ' stop_value ' ) : # si l'element n'est pas traite
2015-05-21 18:45:08 +00:00
xReturn . append ( pList [ i ] ) ; # on met le caractere dans xReturn
2015-05-22 08:33:54 +00:00
pList [ i ] = ' stop_value ' ; # on met un caractere qui nous indique que l'on a deja traite
2015-05-21 18:45:08 +00:00
n + = 1 ; # on met a jour notre indicateur de caracteres traites
else : # si l'element est deja traite
i + = 1
i = ( i + pKEY ) % l
return xReturn ;
2015-05-22 08:25:10 +00:00
# fonction qui fait tourner les rotors (sens horaire) de pROTOR (indice 1 a len(pROTOR)) l'indice 0 etant la liste des premiers caracteres des rotors
def rotateRotorsClockwise ( pROTOR ) :
2015-05-21 18:45:08 +00:00
moveNext = True ;
2015-05-22 08:25:10 +00:00
for r in range ( 1 , len ( pROTOR ) ) : # parcourt les rotors
2015-05-21 18:45:08 +00:00
if ( moveNext ) : # si on doit deplacer le rotor
2015-05-22 08:25:10 +00:00
pROTOR [ r ] = [ pROTOR [ r ] [ - 1 ] ] + pROTOR [ r ] [ : - 1 ] # pivote le rotor de 1 caractere
2015-05-21 18:45:08 +00:00
moveNext = ( pROTOR [ r ] [ 0 ] == pROTOR [ 0 ] [ r - 1 ] ) ; # si le rotor vient de finir un tour, moveNext = True sinon moveNext = False
2015-05-22 08:25:10 +00:00
# fonction qui fait tourner les rotors (sens anti-horaire) de pROTOR (indice 1 a len(pROTOR)) l'indice 0 etant la liste des premiers caracteres des rotors
def rotateRotorsAnticlockwise ( pROTOR ) :
moveNext = True ;
for r in range ( 1 , len ( pROTOR ) ) : # parcourt les rotors
if ( moveNext ) : # si on doit deplacer le rotor
pROTOR [ r ] = pROTOR [ r ] [ 1 : ] + [ pROTOR [ r ] [ 0 ] ] # pivote le rotor de 1 caractere
moveNext = ( pROTOR [ r ] [ - 1 ] == pROTOR [ 0 ] [ r - 1 ] ) ; # si le rotor vient de finir un tour, moveNext = True sinon moveNext = False
2015-05-21 18:45:08 +00:00
# fonction qui affiche les rotors
def printRotors ( pROTOR ) :
for i in range ( 1 , len ( pROTOR ) ) :
print pROTOR [ i ] ;
# fonction qui code un caractere pChar via les rotors
2015-05-22 08:25:10 +00:00
def encodeChar ( pChar , pSIGMA , pROTOR ) :
2015-05-21 18:45:08 +00:00
for r in range ( 1 , len ( pROTOR ) ) : # parcourt les rotors
pChar = SIGMA [ pROTOR [ r ] . index ( pChar ) ] ; # le caractere devient celui au rang de l'alphabet correspondant au rang du caractere dans le rotor r
return pChar ;
2015-05-22 08:25:10 +00:00
# fonction qui decode un caractere pChar via les rotors
def decodeChar ( pChar , pSIGMA , pROTOR ) :
for r in reversed ( range ( 1 , len ( pROTOR ) ) ) : # parcourt les rotors
pChar = pROTOR [ r ] [ pSIGMA . index ( pChar ) ] ; # le caractere devient celui au rang de l'alphabet correspondant au rang du caractere dans le rotor r
return pChar ;
2015-05-21 18:45:08 +00:00
#############################################################################################################################
#############################################################################################################################
#############################################################################################################################
######################################### ############## ############ ##########################################
######################################### ############## ################# ###############################################
######################################### ############## ################# ###############################################
######################################### ############## ################# ###############################################
######################################### ############## ################# ###############################################
######################################### ############## ################# ###############################################
######################################### ############## ################# ###############################################
######################################### ############## ################# ###############################################
######################################### ############## ################# ###############################################
######################################### ############ #########################################
#############################################################################################################################
#############################################################################################################################
#############################################################################################################################
2015-05-22 08:33:54 +00:00
# DEFINITION DE L'ALPHABET
2015-05-22 09:32:21 +00:00
SIGMA = ' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&=+^~@ % ,.?!:[]() {} -_0123456789#$*/ \\ " \' ' ;
2015-05-22 08:33:54 +00:00
# ALPHABET FORMATE EN LISTE
SIGMA = list ( SIGMA ) ;
2015-05-21 18:45:08 +00:00
# NOMBRE DE ROTORS
LEVEL = 3 ; # valeur par defaut
2015-05-22 09:52:11 +00:00
# CHOIX DE LA CLE
userkey = int ( raw_input ( ' Cle: ' ) ) ;
# CALCUL de LEVEL en fonction de la clé
LEVEL = calcLevel ( userkey , SIGMA ) ;
2015-05-21 18:45:08 +00:00
# DECOMPOSITION DE LA CLE PRIMAIRE EN CLES SECONDAIRES
KEY = decomposeKey ( userkey , len ( SIGMA ) , LEVEL ) ;
# CREATION DES ROTORS EN FONCTION DES CLES SECONDAIRES
ROTOR = [ ] ;
ROTOR . append ( [ ] ) ;
# on cree les rotors grace a sigma et aux cles recuperees
for i in range ( 0 , LEVEL ) :
ROTOR . append ( shuffle ( SIGMA , KEY [ i ] ) ) ; # on creer le rotor et le melange suivant la cle
ROTOR [ 0 ] . append ( ROTOR [ i + 1 ] [ 0 ] ) ; # on enregistre la lettre en premiere position dans la premiere entree du rotor
2015-05-22 08:33:54 +00:00
# AFFICHAGE DES ROTORS
# printRotors(ROTOR);
2015-05-21 18:45:08 +00:00
# SAISIE DU MESSAGE
2015-05-22 08:46:37 +00:00
m = ( raw_input ( ' Message: ' ) ) ;
2015-05-21 18:45:08 +00:00
2015-05-22 08:25:10 +00:00
# CHOIX DU TYPE (ENCODE / DECODE)
type = ' X ' ;
while ( type != ' E ' and type != ' D ' ) :
type = ( raw_input ( ' encoder ou decoder [E/D]: ' ) ) . upper ( ) ;
# VARIABLE DU HASH
2015-05-21 18:45:08 +00:00
M = ' ' ;
2015-05-22 08:25:10 +00:00
# ENCODAGE DU MESSAGE
if ( type == ' E ' ) :
for c in range ( 0 , len ( m ) ) :
M + = encodeChar ( m [ c ] , SIGMA , ROTOR ) ;
rotateRotorsClockwise ( ROTOR ) ; # on pivote les rotors dans le sens horaire
# DECODAGE DU MESSAGE
else :
# decalage des rotor en position de fin d'encodage (taille du message -1)
for r in range ( 1 , len ( m ) ) :
rotateRotorsClockwise ( ROTOR ) ;
# pour chaque caractere en partant du dernier
for c in reversed ( range ( 0 , len ( m ) ) ) :
M + = decodeChar ( m [ c ] , SIGMA , ROTOR ) ; # on lit le caractere
rotateRotorsAnticlockwise ( ROTOR ) ; # on tourne les rotors dans le sens inverse
# on retourne la chaine
M = M [ : : - 1 ] ;
2015-05-21 18:45:08 +00:00
print
2015-05-22 09:40:49 +00:00
print ' Enigma : ' , M