X Informatique MP/PC 2008

Thème de l'épreuve Ave Cesar (codages de César et Vigenère)
Principaux outils utilisés boucles for et while, parcours de tableaux
Mots clefs Codage de texte, méthode de César, méthode de Vigenère, boucle for, boucle while, tableaux

Corrigé

(c'est payant, sauf le début): - - - - - - - - - - - - - -

Extrait gratuit du corrigé

(télécharger le PDF)
           

Énoncé complet

(télécharger le PDF)
        

Rapport du jury

(télécharger le PDF)
        

Énoncé obtenu par reconnaissance optique des caractères


ÉCOLE POLYTECHNIQUE
ÉCOLE SUPÉRIEURE DE PHYSIQUE ET CHIMIE INDUSTRIELLES
CONCOURS D'ADMISSION 2008

FILIÈRE

MP - OPTION PHYSIQUE ET SCIENCES DE L'INGÉNIEUR

FILIÈRE

PC

COMPOSITION D'INFORMATIQUE
(Durée : 2 heures)
L'utilisation des calculatrices n'est pas autorisée pour cette épreuve.
Le langage de programmation choisi par le candidat doit être spécifié en tête 
de la copie.

Ave Cesar (zud bdrzq)
On cherche à crypter un texte t de longueur n composé de caractères en 
minuscules (soit 26
lettres différentes) représentés par des entiers compris entre 0 et 25 (0  a, 1 
 b, . . . 25  z).
Nous ne tenons pas compte des éventuels espaces.
Ainsi, le texte ecolepolytechnique est représenté par le tableau suivant où la 
première
ligne représente le texte, la seconde les entiers correspondants, et la 
troisième les indices dans le
tableau t.
e
4
0

c
2
1

o
14
2

l
11
3

e
4
4

p
15
5

o
14
6

l
11
7

y
24
8

t
19
9

e
4
10

c
2
11

h
7
12

n
13
13

i
8
14

q
16
15

u
20
16

e
4
17

Codage de César
Ce codage est le plus rudimentaire que l'on puisse imaginer. Il a été utilisé 
par Jules César (et
même auparavant) pour certaines de ses correspondances. Le principe est de 
décaler les lettres
de l'alphabet vers la gauche de 1 ou plusieurs positions. Par exemple, en 
décalant les lettres de
1 position, le caractère a se transforme en z, le b en a, ... le z en y. Le 
texte avecesar devient
donc zudbdrzq.
Question 1 Que donne le codage du texte maitrecorbeau en utilisant un décalage 
de 5 ?
Question 2 Écrire la fonction codageCesar(t, n, d) qui prend en arguments le 
tableau t, sa
longueur n et un entier d ; et qui retourne un tableau de même taille que t 
contenant le texte t
décalé de d positions.
Question 3 Écrire de même la fonction decodageCesar(t, n, d) prenant les mêmes 
arguments
mais qui réalise le décalage dans l'autre sens.

1

Pour réaliser ce décodage, il faut connaître la valeur du décalage. Une manière 
de la déterminer
automatiquement est d'essayer de deviner cette valeur. L'approche la plus 
couramment employée
est de regarder la fréquence d'apparition de chaque lettre dans le texte 
crypté. En effet, la lettre
la plus fréquente dans un texte suffisamment long en français est la lettre e.
Question 4 Écrire la fonction frequences(t , n) qui prend en argument un 
tableau t de taille
n représentant le texte crypté ; et qui retourne un tableau de taille 26 dont 
la case d'indice i
contient le nombre d'apparitions du nombre i dans t (0  i < 26).
Question 5 Écrire la fonction decodageAuto(t , n) qui prend en argument le 
tableau t de taille
n représentant le texte crypté ; et qui retourne le texte t d'origine (en 
calculant la clé pour que
la lettre e soit la plus fréquente dans le texte décrypté).

Codage de Vigenère
Au XVIème siècle, Blaise de Vigenère a modernisé le codage de César très peu 
résistant de la
manière suivante. Au lieu de décaler toutes les lettres du texte de la même 
manière, on utilise
un texte clé qui donne une suite de décalages.
Prenons par exemple la clé concours. Pour crypter un texte, on code la première 
lettre en
utilisant le décalage qui envoie le a sur le c (la première lettre de la clé). 
Pour la deuxième lettre,
on prend le décalage qui envoie le a sur le o (la seconde lettre de la clé) et 
ainsi de suite. Pour la
huitième lettre, on utilise le décalage a vers s, puis, pour la neuvième, on 
reprend la clé à partir
de sa première lettre. Sur l'exemple ecolepolytechnique avec la clé concours, 
on obtient : (la
première ligne donne le texte, la seconde le texte crypté et la troisième la 
lettre de la clé utilisée
pour le décalage)
e
g
c

c
q
o

o
b
n

l
n
c

e
s
o

p
j
u

o
f
r

l
d
s

y
a
c

t
h
o

e
r
n

c
e
c

h
v
o

n
h
u

i
z
r

q
i
s

u
w
c

e
s
o

Question 6 Donner le codage du texte becunfromage en utilisant la clé de codage 
jean.
Question 7 Écrire la fonction codageVigenere(t, n, c, k) qui prend comme 
arguments un tableau
t de taille n représentant le texte à crypter, et un tableau d'entiers c de 
longueur k donnant la
clé servant au codage ; et qui retourne un tableau de taille n contenant le 
texte crypté t .
Maintenant, on suppose disposer d'un texte t assez long crypté par la méthode 
de Vigenère,
et on veut retrouver le texte t d'origine. Pour cela, on doit trouver la clé c 
ayant servi au codage.
On procède en deux temps : 1) détermination de la longueur k de la clé c, 2) 
détermination des
lettres composant c.
La première étape est la plus difficile. On remarque que deux lettres 
identiques dans t espacées
de  × k caractères (où  est un entier et k la taille de la clé) sont codées par 
la même lettre dans
t . Mais cette condition n'est pas suffisante pour déterminer la longueur k de 
la clé c puisque des
répétitions peuvent apparaître dans t sans qu'elles existent dans t. Par 
exemple, les lettres t et
n sont toutes deux codées par la lettre h dans le texte crypté à partir de 
ecolepolytechnique
avec concours comme clé. Pour éviter ce problème, on recherche les répétitions 
non pas d'une
2

lettre mais de séquences de lettres dans t puisque deux séquences de lettres 
répétées dans t,
dont les premières lettres sont espacées par  × k caractères, sont aussi 
cryptées par deux mêmes
séquences dans t .
Dans la suite de l'énoncé, on ne considère que des séquences de taille 3 en 
supposant que
toute répétition d'une séquence de 3 lettres dans t provient exclusivement 
d'une séquence de 3
lettres répétée dans t. Ainsi, la distance séparant ces répétitions donne des 
multiples de k.
La valeur de k est obtenue en prenant le PGCD de tous ces multiples. Si le 
nombre de
répétitions est suffisant, on a de bonnes chances d'obtenir la valeur de k. On 
suppose donc que
cette assertion est vraie.
Question 8 Écrire la fonction pgcd(a, b) qui calcule le PGCD des deux entiers 
strictement
positifs a et b par soustractions successives de ses arguments.
Question 9 Écrire la fonction pgcdDesDistancesEntreRepetitions(t , n, i) qui 
prend en argument
le texte crypté t de longueur n et un entier i (0  i < n - 2) qui est l'indice 
d'une lettre dans
t ; et qui retourne le pgcd de toutes les distances entre les répétitions de la 
séquence de 3 lettres
ht[i], t[i + 1], t[i + 2]i dans la suite du texte ht[i + 3], t[i + 4], . . . 
t[n - 1]i. Cette fonction retourne
0 s'il n'y a pas de répétition.
Question 10 Écrire la fonction longueurDeLaCle(t , n) qui prend en argument le 
texte crypté
t de longueur n ; et qui retourne la longueur k de la clé de codage.
Question 11 Donner le nombre d'opérations réalisées par la fonction 
longueurDeLaCle en
fonction de la longueur n ? (On ne comptera que le nombre d'appels à la 
fonction PGCD).
Question 12 Une fois la longueur de la clé connue, donner une idée d'algorithme 
permettant
de retrouver chacune des lettres de la clé. (Il s'agit de décrire assez 
précisément l'algorithme
plutôt que d'écrire le programme).
Question 13 Écrire la fonction decodageVigenereAuto(t , n) qui prend en 
argument le tableau
t de taille n représentant le texte crypté ; et qui retourne le texte t 
d'origine. (On n'hésitera pas
à recopier des parties de texte dans des tableaux intermédiaires).

3

Extrait du corrigé obtenu par reconnaissance optique des caractères



X Informatique MP/PC 2008 -- Corrigé
Ce corrigé est proposé par Arnaud Borde (École Polytechnique) ; il a été relu 
par
Céline Chevalier (ENS Cachan) et Vincent Puyhaubert (Professeur en CPGE).

Le sujet propose l'étude de deux méthodes de codage de texte basées sur le 
décalage des lettres dans l'alphabet. On travaille cependant sur une 
représentation
simpliste d'un texte par des tableaux d'entiers. Dans les deux méthodes, on 
commence par écrire les fonctions simples qui permettent de coder un texte à 
partir
d'une clé. Puis on étudie des techniques pour décoder le texte automatiquement,
c'est-à-dire sans connaître la clé. Il s'agit du travail qu'est amené à faire 
tout pirate
qui se respecte.
La plupart des questions demandent d'écrire du code. Il est rédigé en Maple
dans ce corrigé car ce langage est le plus utilisé en classe préparatoire, même 
s'il
est plus destiné au calcul formel qu'à la programmation. D'autres langages comme
C, C++, Caml, Pascal et Java étaient autorisés pour cette épreuve. Les fonctions
écrites n'utilisant que la syntaxe de base, vous pourrez sans difficulté les 
réécrire
dans le langage de votre choix.
· La première partie a pour objectif l'étude du codage de César. Ce codage 
basique paraîtra familier à tout le monde puisqu'il consiste simplement à 
choisir un entier k (une lettre en fait, mais peu importe) et à remplacer chaque
lettre du texte par la k e qui la suit dans l'alphabet. Par exemple, pour k = 1,
on remplace « a » par « b », « b » par « c », et ainsi de suite jusqu'au « z »
remplacé par « a ».
Comme mentionné précédemment, l'objectif de cette partie est non seulement
de rédiger les programmes qui codent un texte, mais aussi de trouver une 
méthode de décodage automatique, basée sur l'hypothèse (souvent vérifiée) que
la lettre « e » est la plus présente dans le texte original. Elle ne devrait 
poser
aucun problème à tout candidat familier avec l'usage des boucles.
· La seconde partie étudie le codage de Vigenère, qui est une amélioration de la
méthode de César. Il s'agit cette fois d'utiliser non pas un unique entier, 
mais p
entiers k1 , . . . , kp (en fait, un mot de p lettres). On code alors la ne 
lettre du
texte grâce à un décalage de k(n mod p) caractères.
À nouveau, la difficulté de cette partie réside essentiellement dans l'écriture 
de
la fonction de décodage automatique. Heureusement, le travail est en grande
partie facilité par l'énoncé, qui détaille de façon précise les hypothèses à 
effectuer sur le texte et l'algorithme à employer.
Au final, le problème est assez long, mais en étant efficace il est possible 
d'en
venir à bout dans les deux heures imparties. Il est bien écrit et très agréable 
à suivre.
On peut passer pas mal de temps à s'amuser avec les fonctions de codage/décodage
une fois le problème résolu en totalité.

Indications
2 Écrire dès maintenant une fonction reste(a,b) qui renvoie le reste de la 
division
de a par b.
3 Penser à réutiliser le code de la question 2 sans tout refaire.
4 Initialiser le tableau contenant les fréquences avec des 0. Parcourir le 
tableau de
sorte que pour chaque nouvelle lettre lue, on mette à jour la case 
correspondante
dans le tableau des fréquences.
5 Pour trouver la lettre qui code « e », rechercher la lettre dont l'entrée 
dans le
tableau frequences est maximale. C'est cette lettre qui servira à calculer la 
clé
de décodage.
7 Utiliser la fonction reste afin d'associer le bon décalage à chaque lettre du 
texte
original.
8 Utiliser une méthode récursive. A partir d'un couple d'entier donné en 
argument,
retrancher le plus petit au plus grand jusqu'à ce que le résultat de la 
soustraction
soit nul.
9 Passer en revue tous les triplets de lettres qui suivent t[i], t[i+1], t[i+2] 
et les
comparer à ce dernier. Faire attention aux indices de début et de fin de la 
boucle.
Utiliser la propriété d'associativité du pgcd pour mettre à jour le résultat au 
fur
et à mesure du parcours.
10 Utiliser les fonctions des questions 8 et 9. Utiliser encore la propriété 
d'associativité du pgcd et appliquer l'algorithme donné par l'énoncé.
11 Bien compter le nombre d'itérations dans les boucles.
12 Voir les différents tableaux t[j], t[j+k], t[j+2k],..., pour j  {0, k - 1}, 
comme
des textes codés par la méthode de César.
13 Conserver la vision de t comme un ensemble de textes codés par la méthode 
César
et les décoder successivement comme dans la première partie. Utiliser une 
matrice
(un tableau de tableaux) pour faciliter la remise en ordre du texte.

Codage de César
Ce corrigé introduit deux fonctions locales (reste et quotient) qui ne
sont pas indispensables pour cette épreuve mais qui permettent de gagner du
temps et évitent d'utiliser des fonctions de Maple qui ne sont peut-être pas
connues de tous.
Rappelons également que tout ce qui est précédé d'un # dans un programme en 
Maple n'est pas interprété par le compilateur, ce qui permet
d'insérer des commentaires dans le code.
1 Représentons les phases du codage dans un tableau. Les différentes lignes 
représentent : le texte d'origine, les entiers correspondants, les entiers 
après décalage,
le texte codé.
m
12
7
h

a
0
21
v

i
8
3
d

t
19
14
o

r
17
12
m

e
4
25
z

c
2
23
x

o
14
9
j

r
17
12
m

b
1
22
w

e
4
25
z

a
0
21
v

u
20
15
p

Le codage de maitrecorbeau avec un décalage de 5 vers la gauche est donc :
hvdomzxjmwzvp

Il faut être attentif au fait que le décalage se fait vers la gauche.
2 Commençons par écrire une fonction reste(a,b) qui renvoie le reste de la 
division
de a par b. On programme cette fonction de manière récursive, en partant de a
et en soustrayant b autant de fois qu'il le faut pour le résultat devienne égal 
à b.
Notons qu'il faut aussi penser à prendre en compte le cas où a est négatif.
reste:=proc(a,b)
if 0<=a and a=b then RETURN(reste(a-b,b));
else RETURN(reste(a+26,b));
# correspond au cas où a est négatif
fi;
end;
Cette fonction peut être remplacée par la fonction Maple irem(a,b).
Cette fonction va principalement servir dans le cas particulier b = 26 pour se
ramener à un entier compris entre 0 et 25 dès qu'on effectue un décalage.
Pour coder un texte, chaque lettre doit être décalée vers la gauche du nombre d.
Pour cela, on construit au moyen d'une boucle for un tableau resultat de même
taille que le tableau t donné en entrée, dans lequel on stocke le texte chiffré.
Pour chaque indice, l'élément rajouté au tableau est le reste de la division 
par 26
du chiffre t[i] auquel on a soustrait d.

codageCesar:=proc(t,n,d)
local resultat,i;
resultat:=[seq(0,i=0..n-1)];
for i from 0 to n-1 do
resultat[i+1]:=reste(t[i+1]-d,26);
od;
RETURN(resultat);
end;
Dans Maple, contrairement aux autres langages de programmation, les
indices de tableaux commencent par défaut à 1 et non à 0. Si vous utilisez ce
langage, il est bien de préciser la convention que vous adoptez pour les indices
car le sujet suppose qu'ils débutent à 0. On respecte ici la convention utilisée
par l'énoncé pour les boucles tout en conservant un code exécutable en 
réajustant les indices dans le corps de la boucle avec la syntaxe tableau[i+1].
La commande seq permet de fabriquer une séquence. Sa syntaxe générale est 
seq(f(compteur),compteur=début..fin). Elle produit alors la
séquence f(début), f(début+1), ..., f(fin). Ici, cette séquence est placée 
entre crochets afin de fabriquer une liste.
Il existe une fonction de Maple, nops(), qui permet de récupérer la longueur du 
tableau ou de la liste placé en argument. On aurait donc pu se
passer du second argument de la fonction (et de même pour beaucoup de
fonctions demandées par l'énoncé). Mais il y a fort à parier que les 
concepteurs du sujet n'ont pas voulu pénaliser les élèves qui ne connaîtraient 
pas
cette fonction.
3 Il suffit d'utiliser la fonction précédente avec un décalage opposé.
decodageCesar:=proc(t,n,d)
codageCesar(t,n,-d);
end;
4 On remplit en premier lieu le tableau des fréquences appelé freq à l'aide de 0
avant de parcourir le texte et de le mettre à jour au fur et à mesure. À chaque 
fois
que l'on rencontre une lettre, on augmente la case correspondante (à savoir 
celle dont
l'indice est t'[i]) dans le tableau des fréquences de 1.
frequences:=proc(tprime,n)
local freq,i;
# on crée le tableau des fréquences avec des 0
freq:=[seq(0,i=0..26)];
# on met à jour le tableau des fréquences
for i from 0 to n-1 do
freq[tprime[i+1]+1]:=freq[tprime[i+1]+1]+1;
od;
RETURN(freq);
end;