Chez Zupple, team building cérébral à Lyon, on adore décoder des messages secrets ! Dans cet article, je vais vous partager la première évolution du chiffrement le plus classique qui existe : le code César Progressif.
Le code César Progressif est une variante du chiffre de César. Au lieu que le décalage dans l’alphabet soit constant sur la globalité du message, celui est incrémenté de 1 à chaque lettre. Ainsi, si la clé nous indique de décaler d’une position pour la première lettre, on décalera de 2 la deuxième lettre, de 3 la troisième, etc. Ce code a l’intérêt de ne pas avoir une correspondance fixe entre les lettres du message source et les lettres encodées.
Ce code est assez peu utilisé, mais je trouvais sympa de voir qu’on pouvait facilement le gérer avec la bibliothèque de fonctions que l’on s’est créé. Voici comment on pourrait l’implémenter :
/**
* Returns the message encoded with the Progressive Caesar cipher.
* Each letter offset depends on the first offset and the incrementation at every letter.
*
* @param {string} message
* @param {number} firstOffset
* @param {number} stepOffset
* @param {boolean} isDecoding - true to decode instead of encode
* @return {string} The encoded message
*/
function encodeProgressiveCaesar(message, firstOffset, stepOffset, isDecoding) {
let stepIndex = 0;
return message
.split("")
.map(function(letter) {
if (!isLetterInAlphabet(letter)) {
return letter;
}
stepIndex++;
const offset = firstOffset + stepOffset * stepIndex;
return shiftLetter(letter, isDecoding ? -offset : offset);
})
.join("");
}
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
// See https://tzi.fr/decaler-lettres/
function shiftLetter(letter, offset) {
if (!isLetterInAlphabet(letter)) {
return letter;
}
return numberToLetter(letterToNumber(letter) + offset);
}
// See https://tzi.fr/js/convertir-lettres-en-nombres/
function isLetterInAlphabet(letter) {
return alphabet.includes(letter.toUpperCase());
}
function letterToNumber(letter) {
if (!isLetterInAlphabet(letter)) {
return false;
}
return alphabet.indexOf(letter.toUpperCase()) + 1;
}
// See https://tzi.fr/js/convertir-nombres-en-lettres/
function numberToLetter(position) {
return getLetterByAlphabeticPosition(
moduloClamp(position, 1, alphabet.length)
);
}
function getLetterByAlphabeticPosition(position) {
if (position < 1 || position > alphabet.length) {
return false;
}
return alphabet[position - 1];
}
// See https://tzi.fr/js/modulos-min-max
function moduloClamp(number, min, max) {
return positiveModulo(number - min, max + 1 - min) + min;
}
// See https://tzi.fr/js/modulos-positifs
function positiveModulo(number, divisor) {
return ((number % divisor) + divisor) % divisor;
}
Il existe aussi des variantes du chiffre de César Progressif où l’on incrémente le déclage tous les mots ou toutes les phrases. Ça donne envie d’essayer de l’implémenter, sachant que les mots ne sont pas forcément coupés par un espace. 😈 Si le sujet vous intéresse, j’avais déjà regardé comment découper chaque mot d’une phrase avec une expression régulière.
Je ne le ferais pas ici… On va essayé de se concentré sur le but originel, c’est à dire développer un codeur / décodeur de Vigenere !