[projet ISN] chiffrement de vigénère [Résolu]

Signaler
Messages postés
9
Date d'inscription
mardi 24 mars 2020
Statut
Membre
Dernière intervention
13 mai 2020
-
Messages postés
305
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
6 juillet 2020
-
on doit rendre ce projet à la fin de l'année, j'ai commencé a faire ça mais je sais pas quoi faire après. Notre pros était sensé nous aider mais avec le confinement ça va être compliqué.
def genere_cle_vigenere(msg_clair: str, cle_vig: str) -> str:
    '''
    fonction renvoyant la clé de vigenère rallongée
    param msg_clair : message
    param cle_vig : clé
    return : la clé rallongée
    '''
    long_msg_clair = len(msg_clair)
    if len(cle_vig)>= long_msg_clair:
        return cle_vig[:long_msg_clair]
    else:
        res = cle_vig
        i = 0
        while len(res)<long_msg_clair:
            res = res + cle_vig[i%3]
            i = i + 1
        return res


ALPHABET = '0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ'

def crypte_lettre_vig(car_clair: str, car_cle_vig: str) -> str:
    '''
    fonction renvoyant le caractère de vigenère
    param car_clair: un caractère du msg_clair
    param car_cle_vig: le caractère de la cle_vig associé
    return: le caractère de vigenère
    '''
    
    return ALPHABET[(ALPHABET.index(car_clair.upper()) + ALPHABET.index(car_cle_vig.upper())) % 37]


'''msg_clair -> msg_vigenere -> msg_transpo'''

print(genere_cle_vigenere('bonjour', 'riz'))
print(genere_cle_vigenere('bon', 'riz'))

print(crypte_lettre_vig('J', 'R'))

8 réponses

Messages postés
305
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
6 juillet 2020
51
Bonjour lola_2015,

Ca devrait ressembler à çà, non? :

# -*- coding:Latin-1 -*-

ALPHABET = '0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ'
CLE_SECRETE = 'LOLA'

def genere_cle_vigenere(msg_clair: str, cle_vig: str) -> str: 
	''' 
	Renvoie la clé vigenère ajustée à la longueur du message clair
	'''

	if (len(cle_vig) >= len(msg_clair)):
		cle = cle_vig[:len(msg_clair)]
	else:
		cle = cle_vig
		i = 0
		while(len(cle) < len(msg_clair)):
			cle = cle + cle_vig[i%3]
			i += 1

	return cle

#Saisie du message
print('\n')
print('''Codage d'un message'''.center(50,'*'))
message_clair = input('\nEntrez le message à coder : ')

#L'alphabet est en majuscules, donc le message doit l'etre aussi
message_clair = message_clair.upper()

#Longueur de la clé = longueur du message clair
cle = genere_cle_vigenere(message_clair, CLE_SECRETE)

#Codage
for k in range (len(message_clair)):
	try:
		print(ALPHABET[(ALPHABET.index(message_clair[k])+ALPHABET.index(cle[k]))%len(ALPHABET)], end = '')
	except:
		print('\nErreur -> {} inexistant dans ALPHABET: {}'.format(message_clair[k], ALPHABET))

input('\n\nAppuyer sur enter pour quitter ...')


A part çà, tu as du taper un peu rapidement, mais je suppose que tu voulais écrire

"Notre prof était censé" et non pas "Notre pros était sensé"

(bien que je ne doute pas un seul instant que le prof en question ne soit également sensé :-) )
Messages postés
9
Date d'inscription
mardi 24 mars 2020
Statut
Membre
Dernière intervention
13 mai 2020

oui, merci de m'avoir corrigé .
oui le programme ressemble a ça, je viens de créer le compte je ne sais pas encore comment fait pour afficher un programme.

Notre prof bous a dit de faire d'abord une fonction pour la clé (la rallongé et la raccourcir quand il faut), une autre pour donné un chiffre attitré aux lettres ( on en a 37 car on a mis l'espace, et les nombres de 1 à 9) ensuite il nous à demandé de faire une fonction sur le message codé de Vigenère ça j'ai pas compris
Messages postés
305
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
6 juillet 2020
51
Bonjour lola_2015,

1) La fonction pour la longueur de la clé, on l'a déjà:
def genere_cle_vigenere(msg_clair: str, cle_vig: str) -> str:

2) Pour attribuer un chiffre aux lettres, on le fait dans l'instruction suivante:
print(ALPHABET[(ALPHABET.index(message_clair[k])+ALPHABET.index(cle[k]))%len(ALPHABET)], end = '')

ALPHABET.index(message_clair[k]) renvoie la position de la k ieme lettre du message clair dans ALPHABET, par exemple, si la lettre est A çà renvoie 11

3) La fonction pour le codage Vigenère: je n'ai pas mis çà dans une fonction, mais on peut le faire aussi, le codage on le fait ici:
for k in range (len(message_clair)):
	try:
		print(ALPHABET[(ALPHABET.index(message_clair[k])+ALPHABET.index(cle[k]))%len(ALPHABET)], end = '')
	except:
		print('\nErreur -> {} inexistant dans ALPHABET: {}'.format(message_clair[k], ALPHABET))


As-tu récupéré mon programme et l'as-tu testé ?
il fonctionne et répond bien au problème posé
On entre un message en clair et il renvoie le message codé avec la CLE_SECRETE = 'LOLA'
Cà donne çà:


Est-ce qu'il te manque encore quelque chose ?
y-a-t-il des choses que tu ne comprends pas ?
Dis-moi tout
Messages postés
9
Date d'inscription
mardi 24 mars 2020
Statut
Membre
Dernière intervention
13 mai 2020

notre prof nous a dit qu'on pouvait utiliser la fonction dico ou dictionnaire (je me rappelle plus trop) mais il a pas expliquer pour quoi .
les signe "+=" dans le programme signifie quoi ?
Messages postés
305
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
6 juillet 2020
51 >
Messages postés
9
Date d'inscription
mardi 24 mars 2020
Statut
Membre
Dernière intervention
13 mai 2020

Une version avec des dictionnaires:
Cette fois il y a bien une fonction avec attribution d'un chiffre à chaque lettre
En affichant le résultat, je l'encadre avec >>> et <<<, car si le caractère espace est le dernier du message codé, ca ne saute pas aux yeux et pourtant il fait bien partie du codage !
Exemple : >>>dz1lzzv <<<

# -*- coding:Latin-1 -*-

ALPHABET = '0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ!'
CLE_SECRETE = 'LOLA'

def genere_cle_vigenere(msg_clair: str, cle_vig: str) -> str: 
	''' 
	Renvoie la clé vigenère ajustée à la longueur du message clair
	'''

	if (len(cle_vig) >= len(msg_clair)):
		cle_ajustee = cle_vig[:len(msg_clair)]
	else:
		cle_ajustee = cle_vig
		i = 0
		while(len(cle_ajustee) < len(msg_clair)):
			cle_ajustee = cle_ajustee + cle_vig[i%len(cle_vig)]
			i += 1

	return cle_ajustee

def assigne_un_entier_aux_lettres(message, cle_ajustee):
	''' Créé 2 dictionnaires:
	clé = une lettre du message, valeur = rang de cette lettre dans ALPHABET
	Idem avec la clé ajustée
	'''

	dico_msg = dico_cle = {}

	for k in range (len(message)):
			if (message[k].upper() in ALPHABET):
				dico_msg[message[k]] = ALPHABET.index(message[k].upper())

	for k in range (len(cle_ajustee)):
		if (cle_ajustee[k].upper() in ALPHABET):
			dico_cle[cle_ajustee[k]] = ALPHABET.index(cle_ajustee[k].upper())

	return (dico_msg, dico_cle)

def codage_decodage_vigenere(message, cle_ajustee, dico_msg, dico_cle, coeff):
	''' Codage ou decodage du message avec les dictionnaires '''

	message_resultant = ''

	for k in range (len(message)):
		message_resultant += ALPHABET[(dico_msg[message[k]] + dico_cle[cle_ajustee[k]]*coeff)%len(ALPHABET)].lower()

	return message_resultant


#Saisie du message clair
print('\n')
print('''Codage d'un message'''.center(50,'*'))
message_clair = input('\nEntrez le message à coder : ')

#Longueur de la clé = longueur du message clair
cle_ajustee = genere_cle_vigenere(message_clair, CLE_SECRETE)

#On assigne un entier à chaque lettre
dico_msg, dico_cle = assigne_un_entier_aux_lettres(message_clair, cle_ajustee)

#Codage
message_code = codage_decodage_vigenere(message_clair, cle_ajustee, dico_msg, dico_cle, 1)
print('>>>{}<<<'.format(message_code))


#Saisie du message codé
print('\n')
print('''Decodage d'un message'''.center(50,'*'))
message_code = input('\nEntrez le message à decoder : ')

#Longueur de la clé = longueur du message clair
cle_ajustee = genere_cle_vigenere(message_code, CLE_SECRETE)

#On assigne un entier à chaque lettre
dico_msg, dico_cle = assigne_un_entier_aux_lettres(message_code, cle_ajustee)

#Decodage
message_clair = codage_decodage_vigenere(message_code, cle_ajustee, dico_msg, dico_cle, -1)
print('>>>{}<<<'.format(message_clair))

input('\n\nAppuyer sur enter pour quitter ...')

Messages postés
305
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
6 juillet 2020
51
Je te renvoie le programme, car il y avait une erreur dans la fonction
genere_cle_vigenere
En effet il faut écrire cle = cle + cle_vig[i%len(cle_vig)] et non pas
cle = cle + cle_vig[i%3]
sinon, ca ne marche pas pour n'importe quelle longueur de clé !
Et le codage Vigenère est maintenant dans une fonction

# -*- coding:Latin-1 -*-

ALPHABET = '0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ'
CLE_SECRETE = 'LOLA'

def genere_cle_vigenere(msg_clair: str, cle_vig: str) -> str: 
	''' 
	Renvoie la clé vigenère ajustée à la longueur du message clair
	'''

	if (len(cle_vig) >= len(msg_clair)):
		cle = cle_vig[:len(msg_clair)]
	else:
		cle = cle_vig
		i = 0
		while(len(cle) < len(msg_clair)):
			cle = cle + cle_vig[i%len(cle_vig)]
			i += 1

	return cle

def codage_vigenere(message_clair, cle):
	''' Codage du message clair avec la cle'''

	message_code = ''

	for k in range (len(message_clair)):
		try:
			message_code += ALPHABET[(ALPHABET.index(message_clair[k])+ALPHABET.index(cle[k]))%len(ALPHABET)]
		except:
			print('\nErreur {} inexistant dans ALPHABET: {}'.format(message_clair[k], ALPHABET))

	return message_code

#Saisie du message
print('\n')
print('''Codage d'un message'''.center(50,'*'))
message_clair = input('\nEntrez le message à coder : ')

#L'alphabet est en majuscules, donc le message doit l'etre aussi
message_clair = message_clair.upper()

#Longueur de la clé = longueur du message clair
cle = genere_cle_vigenere(message_clair, CLE_SECRETE)

#Codage
message_code = codage_vigenere(message_clair, cle)
print('>>> ', message_code)

input('\n\nAppuyer sur enter pour quitter ...')
Messages postés
9
Date d'inscription
mardi 24 mars 2020
Statut
Membre
Dernière intervention
13 mai 2020

Encore merci, vous êtes mon sauveur
on doit faire un chiffrement de Vigenère + une transposition rectangulaire.
On a pas eu le temps de le faire les transpositions ( blocus, les épreuves des 1er, semaine de bac blanc, le confinement) je sais pas comment faire, j'ai cherché sur internet mais les réponses ne m'aide pas.
Messages postés
305
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
6 juillet 2020
51
OK,

Par contre la transposition rectangulaire, je ne connais pas du tout …
Messages postés
9
Date d'inscription
mardi 24 mars 2020
Statut
Membre
Dernière intervention
13 mai 2020

Il y a pas de problème, encore merci pour votre aide.
Pour déchiffrer Vigenère on fait juste l'inverse ?
Messages postés
305
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
6 juillet 2020
51
Oui, on fait l'inverse, il faut soustraire les index au lieu d'additionner :

Puisque l'index d'une lettre codée dans ALPHABET = index lettre du clair + index lettre de la cle :
message_code += ALPHABET[(ALPHABET.index(message_clair[k])+ALPHABET.index(cle[k]))%len(ALPHABET)]


pour retrouver l'index du clair, il faut donc faire index du codé - index de la cle

Donc faire une fonction similaire à codage_vigenere : decodage_vigenere, qui reçoit en arguments le message codé (mis en majuscule) et la cle (calculée avec genere_cle_vigenere)
et faire et remplacer l'instruction ci-dessus par:
message_clair += ALPHABET[(ALPHABET.index(message_code[k])-ALPHABET.index(cle[k]))%len(ALPHABET)]

 

à la place de message_code+= ……..

(si tu fais un copié/collé de codage_vigenere, n'oublie pas de remplacer message_clair par message_code et in versement :-) )
Messages postés
305
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
6 juillet 2020
51
Bonjour lola_2015,

a += 1, c'est un raccourci pour a = a + 1

un dictionnaire, c'est un genre de liste avec des clés pour accéder directement aux éléments:

mon_dico = {'nom':'toto', 'age', '20'}

print(mon_dico['nom'])   #affiche toto

#les cles et les valeurs ne sont pas forcément de chaines de caractères:
mon_dico = {0:10, 1:20}
print(mon_dico[0])


Il y a plein de docs à ce sujet sur le net :-)
Messages postés
9
Date d'inscription
mardi 24 mars 2020
Statut
Membre
Dernière intervention
13 mai 2020

bonjour phil_1857
A votre avis, ils vont nous faire passer l'oral d'ISN cette année ?
Messages postés
305
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
6 juillet 2020
51
Bonjour lola_2015,

pourquoi me demandes-tu çà ?

Sinon, as-tu vu ma dernière réponse du 29 à 18h40 : le programme Vigenère réécrit avec les dictionnaires ?

Et ma réponse dans l'autre demande à propos des transpositions rectangulaires ?
Messages postés
9
Date d'inscription
mardi 24 mars 2020
Statut
Membre
Dernière intervention
13 mai 2020

oui j'au vue merci, le lien pour la transposition rectangulaire m'as beaucoup aider merci.
désolé j'ai envoyé le message au mauvais chat
Messages postés
305
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
6 juillet 2020
51
Pas de problème !

C'est toujours un plaisir de t'aider :-)