Malgré le succès de votre collègue Georges hier pour casser le chiffre allemand qui vous a permis de sauver plusieurs soldats d’une offensive surprise des Allemands, une terrible nouvelle est arrivée ce matin.
Il semblerait que les Allemands utilisent une nouvelle étape avant leur méthode de chiffrement que vous n’avez toujours pas réussi à comprendre.
Alors que tous les espoirs semblent perdus, un espion arrive en courant dans votre bureau ! Il a réussi à voler le début du télégramme intercepté ce matin lors de la nouvelle étape de chiffrement allemande !
Cela ne devrait pas être très compliqué de casser à nouveau ce chiffre avec vos compétences.
Si vous trouvez une chaine :
CYBNTOTO1234
Alors le flag est CYBN{TOTO1234
Solution
On nous parle de chiffrement allemand. Avec une rapide recherche internet ("chiffre allemand cryptographie"" ou "morse allemand cryptographie"" par exemple) on tombe tout de suite sur le chiffre ADFGVX.
Ce chiffrement correspond en tout point à ce qu'on a, voici son fonctionnement :
Fonctionnement
Etape 1
On défini un tableau de conversion de 6x6 et contenant toutes les lettres et tous les chiffres répartis arbitrairement (26 + 10 = 36, soit 6x6 ça tombe bien). On attribut à chaque lignes un identifiant sous forme de lettre, dans l'ordre : ADFGVX. On fait la même avec les colonnes, c'est à dire la première colonne aura pour identifiant A, la seconde D et ainsi de suite.
Ensuite on va remplacer chaque lettre de notre texte par un code correspondant à l'identifiant de la ligne puis celui de la colonne où se trouve la lettre dans le tableau. Autrement dit chaque lettre va être remplacée par deux lettres. Voici ce que ça donne avec le mot username :
Etape 2
Notre username s'est donc transformé en XDXVAVDAVFGCFGAV. Maintenant on va décider d'un code dont la taille est un diviseur de celle de notre texte initial. Reprenons notre exemple, ici le texte fait 8 lettres donc on peut choisir un code de taille 1, 2, 4 ou 8. Pour l'exemple on va prendre un code à 4 chiffre : 4231.
On va ainsi construire un tableau de permutations de 4 colonnes identifiées chacune par notre code. Donc la première notée 4, la seconde 2, la troisième 3 et la dernière 1. On place chaque lettre de notre texte transformé de gauche à droite et de haut en bas. Concrêtement ça donne ça :
Ensuite on vient simplement remettre les colonnes dans l'ordre croissant selon leur identifiant :
Et enfin on lit les lettres d'abord de haut en baspuis de gauche à droite, au global ça donne ça :
On se retrouve avec VACVDVFGXDGAXAVF. Les allemands passaient ensuite les lettres en morse pour les communiquer, les lettres ADFGVX ont été choisies car elles ont un code morse très distinguables les unes des autres à l'oreille.
Comment casser le code
Maintenant que l'on sait comment le chiffrement fonctionne, on répète les étapes dans le sens inverse. Pour ça on :
Décode le morse
Place les lettres de haut en bas puis de gauche à droite dans le tableau de permutations
Réarrange les colonnes du tableau de permutations
Lit les lettres 2 à deux de gauche à droite puis de haut en bas
Pour chaque groupe de deux lettres, on regarde à quel charactère il correspond dans le tableau de conversion
Sauf qu'il y a plusieurs problèmes à résoudre :
On ne connaît ni la taille du code ni le code utilisé en lui-même, donc le nombre de colonnes du tableau de permutations => Solution : on regarde les diviseurs possibles et l'on brute force les permutations si elles ne sont pas trop nombreuses.
On ne connaît pas le tableau de conversion => Solution : on a le début du texte déchiffré fourni, on pourra donc reconstruire une partie avec ça et le reste on le devinera à la main
Ici le texte chiffré que l'on a fait 7796 lettres, les diviseurs sont donc 1, 2, 4, 1949, 3898 et 7796. Vous en conviendrez, la taille de code la plus probable c'est 4. Un code de 1949 chiffres ou plus c'est pas possible, et on pourra toujours partir sur 1 ou 2 après si ça ne fonctionne pas.
Combien de permutations possibles pour un code de 4 chiffres ? La réponse en python :
Un brute force de 24 possibilités c'est largement faisable donc on est parti.
On va commencer par construire notre tableau de permutation :
3. et 4. Bruteforce du tableau de permutation et création des groupes
Ici on va créer toutes les permutations possibles et pour chacune d'entre elles assembler les lettres 2 à 2 comme vu dans les explications :
5. Conversion des groupes en charactères
Maintenant on va s'appuyer sur le texte en clair, on dit que le premier groupe se converti selon le premier charactère du texte, le second groupe selon le second charactère etc.
C'est à dire que si le premier groupe est XA, comme le premier charactère du texte est C, on remplace tous nos groupes XA par C
Dans le cas où la permutation faite pour créer les groupes n'est pas la bonne, il y a un moment où on va essayer de convertir avec une lettre un groupe déjà converti par une autre lettre.
Pour reprendre l'exemple, imaginons que notre 5ème groupe est identique au premier (un XA), comme le 5ème charactère du texte est V, on voit bien que ça ne colle pas. On aurait dû trouver la lettre C en 5ème position dans notre texte hors ce n'est pas le cas donc on voit bien que la permutation n'est pas bonne.
En python ça nous donne :
Execution complète du script
Le script au complet :
On y est, 2 permutations fonctionnent : 1, 2, 0, 3 et 2, 1, 3, 0. Cependant on remarque qu'à la fin du texte il reste des groupes qui n'ont pas été changés
En lisant attentivement on peut facilement deviner les lettres qui remplacent ces groupes. Prenons la fin du texte :
On peut clairement lire L? FL?G ?ST CYBN OLD CRYPTO ?S TH? B?ST CRYPTO. En inspectant d'un peu plus près tout le texte déchiffré, on voit qu'il ne contient pas les charactères A, E, I, K, W, 2, 5 et 6, on comprend donc que :
# Morse décodé
cipher = "XGXFVXDGGFFXAFXXXXFGAAVGAVDXAGAXXXXVGVXXXGGDFXFXFDAXFXFFAAFVDGDXGXFAAGGXXVGXFXFFFXGXGGFGGXXGXXFFXFXGVVGGDGXXGVXXFFAAFVDFGDFAGDAFXXVGFGXXXXFXGFDVXGAFFGFGFFGAGFVFVFGXGGFGFXGXXVVVXFVGGAXGXAFFXVXGGXXFDGFDDGGFXDGFGFXFXXDDGFGXGXAGAXXGXXFAGXDFXGFGXXAXDXXDFFXDAXDXXGVFXGFGXXXGGXAGXXVAXGXGFVAGXFXGXFXFXGXVGGGFVAGDAFGGXFXFDAXFGGVFFFGGAGXGGGXXXGXGFGXXFGDGXGGGAFGDFGAXVAFAFGVXGDGAAVDXVFXVXFGDFFFGAGFFVXGAAVDFXXXXAGXGXFGGXXXXDGFFAVADDGXFXXGFDAXDXGVDXFVXXDFGFGDAAXGVFFXXFAVXVGGXFGXXGGGFGGAFGGVFGVVAVGGFVXGFXXGXXGGGVXFAFFGXXDGAAFDAGXAAXXDGVAFAXXXGFGXGGFXVVDXXAXXGGGAGAXADFGGXXFGGAFXGVGFXFDGAFXGXFFFXXVGXVAXVGXDDGGXXGFXDGXGADAXDXDXVXXDXXGVXFFXFFGXXGFFFXGDFXFAXXXGFXGAFAXXGFXDGXXXVGGFXFFGDFFGAGFFGFXFFGDGXFGVGXGFAVGGGGAAXDXVFGAXGGXFXAFGVXXGXXXFXGFGFFFDXGFFVFVFFGVXXFDFFXGGFGFGXVAFGGFDGDFXDGGXGGFFXAAGGXFGGDGAFGADVAAFXVAFAXXGFGDFXFXFGGAGGFGGXFGFFAVXFDFVXGAGXXVFGGAFFFGAGFFGAVVXXFXGGFXFXXFXXVGDAGDXXGVXGGGXVAAGGAXGXGFGAFGAFVXGXVFGXDAGXDXDFXAXFXXFXGFGXAFXGVXDGXDFFXAGGFGFXXVXDAFGXFVXGVAFGXDDGGXGXVXFVGXAFGFXFFVAXXGXXXAFXAFXGGFFVGXDXXXVFGFGXAFVXGGGGXFDAGVFGFGFGXGXGGAFVXFFFFFFFFGXDGVFFXVGXDDGGXFGAXVFXVFFDAXFGGXFGXXAGFFAGFDAGAGFGVGXFGFAAGXXGFFXGXFGAXFVXGDAFXVDXXFGXFFXFDGDFGFXXVXGXXFFXFXDGXFGDGFDAGXFGXXADFXGGXGFXXVFXXVGXGFFXVVFXAXVDGGXVGVFGXXFGFGFAGXVFXGGXFDGXXDFXXFGFGADFGGGVFGXXDXAFFFFFVXXGXDAFGGFXXVAFGFXGXGXVAGGGFGVFFXXFGDDGFVDGFXXGFGFXFXFAFXXXGXGXFGGDFFGGVXGXXVGXFXFFGFXVGFXFXFGAXGAXGGGXADGVDGXGGVGVXGFVDAXVFGGGAFXDXXFAVFGGXFDFXXXGGXGXGAGGGXXVGFXGVFXFFXFGGVFVXXVXVGAXVDDDFXGGXXGFGGFVGXAGGAXFGXGVVFGDAGDFGGXFGXGGFDFXVXXVFFGGXFFFGXDXXGDAVGFFAXXGXGGXXGGXXGDFGFXXGGXGFXXDXGVFFGXAVGGXFADDFAFVDFGVAFGVGFXFXVFDGVFXXFDGAGAFDGFFXFGFXFGXGXGXXVGXVXXFGDAXXXAFGXDFFXXGFFGGVGXFGVGFFAGXVGVGAGXGFFGFFGGAGGAGFAGGVFDAAFXDGXXAXFGXGXFVGAGGVVFFGVAFGXFGDXXVXXDAXFDGXXAXVDDXFGXVVFVXXGXXVAXXAAGGVGFXFAGGXVAXVAAGGAVAGXGFGGFGGAGGGXGGFGFVAFGFAFDGXDFVVVVAXGGGDFGFXDGXDXFVXGXFXFXGFXXGAXXXDDGGGVVXGXXXVXFGFFXVDGXVDFDFFXVFGXXADFXGGGDGFGAGXGAFXFFGXADGXFAAFFXXXXXGDGXXGGGAGAGFDVADAAGVGAAVGAGAAGGGFAFGGADGFXXXXAXFFDGAGXVGGFGGXVVVGGFAGXXAGGVXXXFAFFDXXGGAFXXFFGVGVXXFFXVXVGAGXGGAFXFFDAVGAVDXFFFAGGGXXXXVVGXGGFAGFXFFXFFGXXGFXFDXXFAGXXXXVADXFGXXXAGFXFFGFXXFXXXDGAAXGDVAGFFXGDXXXXFAGFXGFDFFFGAGFFVGADXFXXFGXDDFGFDGVDDAXDXXGFDFFFGXGFDAGXFGXDAXGVGFDDGFGXADFXDDGFGFGDAXGVGAGVVAFFDGDXGGGXGGXGFDFXGGGGFGFGXXVAVFXXXVVAXAFDXXGDVAXFXXXGXGXGXGFGFGXXXGGFXGXGFXVGFGXXGFGFAFGXXFGXXXXXGGXFGDAAAFXXAFFXVXGGDFXXGGXFFGXVVGXGAFXFDFFDFGXGDGXXFFGGFAXGFDDGVGAXVADGGFXXGXXVFGXAGFFFXAGAAVDAXGDFVFAFVDXDVAXFGGGXAVDGFGFFDGFFFVVGAFGXGXGFFVFXVGXVGGXXGDXAAXVGGFFAXXGXXFXADVGXAGGXDVFFXGXXFXGGGGVXXFXGAXFFXVFXDGXGFXDXXXGGGDAFGAXFAXFFDGXFFGXXFDDGXDAAFFAGAAAFFAAFVDFGDAAGAXAFXGFFFFXGFVVFDDFFFFXFFVVFGXXGDFFXDFXXXGAXGGXFXXGGXAFAFFVAXGXDXXDDGDGFXFGXGFFXFGXDGGVAFGXAXXGDAGAGFFDGGXGGGFGFDXVFGGXXAFGGGXXVFVFFXDDXXGFVXGDAXXVGFGVVFVXXGVGGXFFAAXVGDFFXGFGADAFXXVXXXGFFVGFXFAFXXGGFFFXGFFFVGXAFFXVXGVXAFGGFDXXAGDGFVFAGXXXVFFFGAAXDVAGGXXXVDGXXFXXGFXVGGFDAGFXDXXGGFVXFAXGDDAFGXXAAXDFAAFFGFXVDFXXDGFAGGAGXDGAFGGFFAXVDFXVFGXDGFGFGVAXFGGGXFGXFGGAGAXFAXGFXGXXGXGGAFGGFXXDGVGGFDXVGFXXVGGGXGVXGFXGXVXXGAXDFAAXDFGGXAGFXAFGAXFAXFGXAFFFFXVGXGFXDXFXXFGVGAGVXGFFDXGXGXGFGFGXFGGGXGGXDGFXAFGGFFXFGADVGAGFFFAGFXVXAVFDAGAFGAGGGXGXAGXGFAXXXGAXGDFFXFAXFGVXDFFGXVFGGXGXXAGXVAFGXXGGGAAXGDFFXXGXVADGDAVDFDXFGFXGGXVFGXXGGDVAXFAXGFGXDFXDADGGFGXFGXGFAFAXVDGXGGDGFFXFGFXFVGFVXAXDXADAGFFAXGVDADVGFGGGFAFGGXGXXGGXAGAFGGXGGGDXXAGFGVFVGGFXAXXFXGVVAXVGAXXDXDGVDFXDDXXFGGXDXXFGGGGFXDXXDDGXFGXAXFVFGXFFXFAFFXXGGGFGXGFAVFFGFAAGGXXFGGAXDDAVGFGVAVDFGXGXXVDAFXAXAFXXXXXDGXGGXVGXXGFGGAFFXAXVDGXFVGFDAXFXGGXGVDGGAGVVAGVFAFVXAVFFGXAGXAXGFGGDXXGGAXFFFVXFVGFFGXXGAXVDDXFVGGGVFDGXFGXVFVXXGXXVAXGXDAFXAXGGGGGDAGAFXXVAAGGVFGXXFGGFFXXXDGADFGGFGFFGGXGFFXGXDGVXGVXXVXVXFGXVFDGFFFXGFFDFXDXGFVGXGXXXAFGXGXAXVDGFVVGDAAAXDADXFGVAFGXFDXXXDGAGAFDGFFXFGVFGXGVFDAFVGAGXGGXXXVFGXDFDFFAFVDFFXFGXAGXGDXXGGFGVGGGGAAFGDXVVGXGFGFFXAGGGGFGADVGDXFFGVAXGGXXXXXAGAFGDGAFXXGFGDXFGFFGDXFAAXGDFFXFAXFXFFFXFGVXDGFXVFGXXAFGXFGDFGGFGFFGFXAVDFDXFGXAAAAFADFDGGFFDDFAVGDGVFXFAVDFFDDFVGDVXDFGFDDFDDGGGGFAXGDFXAGGDFFVXVGFDDFGXFFFDAAGGGFDGVFGDGADFDFADADGDDDAGGGGFGAADAGGFFDXGGGFFFDGAGFDGFDAAFFGVFDDFFAXGDFFDDXDFVDFDFDDDFGGFVFFDDDFDAXGFFFGDDVGFADDVDVDXDDFGDDGDAADGDGGGXAFFFFDGFDFDGVAFGDDDDFFFGGDGDGFFAVDDAFDFFDDDAGFGGFFGGFDDGFGFFAAGADDDAGFXGGGXDGDFAFAFDDDFFGADGFAGGGDAGFFFGXGDFFFGGDFXGFDDFFGDDFDFFGFGFGFFGDDAFFDGFGFGFFGFGGDDFFDDFGDDDDFAGFFFFFFDDGAFXXDVFFDAVDGDAFDDFFFDDVGAXFGGFFDAFGDGGFDGFGGFFFDAFAGDDAVGFFGGDFGDAAGVDDGFFGVFFXFAAFFXGXGGDGFFDVGGXGGDFFGDDDGVAFGGDDGGDGDAAAVGGGGGFFFFAAGGGFGDFGFDDFAFFXXFGAAGGGFFAFFGFXFGFFXADFDGDGDAFFDDGFGGGFDVFGDDVFFGGFDFDFADDDDFFVAGXVFDFDGDGGDGFVGFDFVGFFFFDDGAXGXXDGVXDAGDAADDXAXFXVFGVAAVFDDGGDDDGVGGFVGXXVDFDFVVGFGGDDFAXFGAFVFFFVDXAXVFGXDDFDFFGFFDAVFVFFFGAFDFFDFVGXGAFGFFGDDAXGVGVDADAADGGGFDGAADDFDAGDFFFGGGDGFDFFFGGGDAAXDFGGGFGGDGFFGGFAFDAXXFGADGDFGDGXDDVFFGDFFGVGGGFDGGGFFGGDGDDFGGVGGFDAVDGDAGFXAFADAFFDFDFGGAXGDFFGGAGAXDFFGDDFFFFGFFDFFDFFVFGGGDDXGVFFFFGAVGFAXDFDXXAGFFDXFDGXDGDGGFGAVFFDADXDAXGFFFXGGGDGXFGDGFGDFFDAVAVAGXFDGADDGAFAGFDGXFVXFDVFGFFGFAFXGGGVDFFAGGGDADGAFFFGAVAFGGFFGFGDGDFVDFGAXGFDVFFDXFGDXVFDFDGDGAFXGVGADGAFFADDFFDFGGGFXAGDAVDFDVDADFGFDGFDGAAFFDFDAVFXGGGDGFDGXFGFDAVGVXAAFGDGGADXVDDFDAGGFADXDDGDGFFFGGFFDGDFGDFGAGFDGDGXGVFAFDDDXFFGXAAFFFAAXGFFDAVFFGFGDDADGGDGFFGVGFGAFGDDFFFAFGDDDXDFVAFGAFDDAAGDFFDVFGVXGXFGDVFAADAVVFVAVFVAGAGDDDFFXDGXVGXFGGDDDGDVVGDVXVDFFGFFDFFXVDDFDDVAAFDFDFGGGVGAAVFXFDAFGGGXFGFDFDDFDAFGVFDFDFGADFDFFDAFFDGFVDFDAGFDFFXFGGDFFDGDVXGGFFGFAAGFFGXGGGAAXDDGDFVGFDFDDDAGAAGGGDVFDFFFGDDADGFXGDFFFFFFDGAFGADFGDDGXGADGDGDGFFGFDFDFGFFDFFGGVAXGGGXGGAXGGDGGAGAFDDFXDFVAFDDFGAXDVAGGFVGGDAAFFGXFGDDFGGAGGGDDFFGGFGGGFDAFFGGFDFDDADGFGFVAADXADGDFGDXFFGDGFFAAGDGFFFDAXVVDFDGVDAGDDGVFGDFFGDAGFFGDGFDFFGAVFVFFDADADGFVDDVGADADDFXAAFVFXFGDDVAGFFDXDFDXFFGVGXAAFVVDDDDAXFGDDFAVDGGGDGFGGVFXVGGXAFDFFFFGAADDVVVGXGGDDGDVADDAFGAFFGADDGFGFGXXAFGFGGGFGDDGVFDVFDFGFXDGFDFGAAGXFGAFDDDFXVDDFFAXFDFGGFFDAFVDFGDVXGFFDGDFGDFGFVFVFVGGFDGFFGGADFDGFFDFDGVAAAGVFAFGGDDFDAADXFXGGDADDFDDGGAGDAGFGFGGDDXXAGFXFFFFFDDXDAGGGGFDFDFFDDGFGDDDGVDFFFFDFDFGFGVXDAGDAAAFFDXDDGDFGGFVFDAGDAFFDDFDDFGFFDGDVFAXGVADGFFFGDFGVXDAGDAADGDADDGDDGFGAXFDFFDFGDGFFDGVGDVGGFGAGGGGVFFFADFGDAFFXDXDVGFGDDAFDAVDGDAAFFDVGVDFFDVFFFGAVFVFFGFFAAFGFXFDFFVFFDDVDDGDGDADFDDFFFDGDFDDDFFFGGGDGDADFFFVDDADFGXFGFFGGDGFDFGDGDVDAFGFGDGGDGDDGVAFGFDFDFGFAGGVAAADGFAFDDFDADFGAFFGADDFGAADAGDGFGFGDAXGAGDFDGXGGGFGGDGFDGDGDAADGDGGDGXGGGFFFDDDFDFFDDAFFFFFFGGDGGDFFFVFFGDDDDFFGGGFVGDFDAAGFDXGFFGDGFFVDGFGFAFVFFFXADVGFXGFAGGAGGDGFAGGFDGFFGFFAVAGFVXVGAFDDAXDADXGDXDFFFGGXAGFFFGVFDGFGFGGFDFXFFFAFDADFDDGAAFFGFGGFFGGGFFVDAXGFAFGDGFXGAFGDFGGDGGAFFFGDFDAFVDDDDFFFDGFFAFDDGFDGFDAAFFGVDDFFDFDGXDFFAGDAXGXFFFGFDDDDXGXFAFGDFDGDGXGGVAGFAGFDDFDFGDFFVXGGFAFXDDFFGGAGFFDFVFDVGGDFFDFFGDAAAGVDFDFGDGDGGDGGFFVFGAFGFGADDFGXGGGAVFDGDFFAFAGDGFXGFAFDDFDXXAAXFGDDAFGXAGFDDGADVDGFDGFXGVAADDGAGVXGDGDGGDADGFFGGFAXGDAADGDGVDGGDFVDAADFVFFVDDGFDXGFDFDGFAFAFGXGAFXFFFGVFGDDXGGDAFGDFDFXAFDFDGDXFGFDDFFGGFXGFDGFFFFDAVFGVFVGVFDGFAXDGFGGDAGXAAFDGAVFGFGFFGGFXGAVFVGGDFFGDFFXFFXGFVAAAGGDDFFFGGAGADXGGDAFGADVDDFGDAGDGAFGFFVXGGFGGDDDVGDGFGAGVGFGGDGGAFFDGXFGGDGGVDGFDAFFVDFFXDDDGGDDDAXGDGGGFVGVXDADFGVDFAFDVXFGGDADDVFGFDFDAFDGFDDFDDFAFFGDGDFDGDVFFAFDADFVDDGFVFFFDDGFFGFGAFFGVDDGDDGAGXXGAFXFGDFDFGGGVFFFDVAAGXAFGGFFAFDFADFDGDFGFAFXFDGFAGGFFFVDXGDAGVGDFADDDVFAFFFGXAAGDAFGDGGFFADVGGGFFGXGFFGGFVFDDAGDGFDFVXGDFFGFFFAGFDADGFGDGDFGADVFDGADFGGFFVFDVXFAGFGFVDXDFGGDFDAGGVFFGGFXFGGFAFXADDFFDXFVAAFVDGDFDDAFVDFDAGGFFAGAFGGGFGGFVGGGDGDFGDGAGDGDGFVFFDFFGVFAFGGFGAFXFDDFAGGVGDDGFDGAFGDDVAGGGDGDFGGVGFFGGVGFFDDFDDAGVGDFFGFFVDFDFDFFDDFAFDGFFGGFFVDGGVGAFDGFAFGGDGVDAGDAAGXAAGFGFVFGAVFGAFDVDAXFGDDFAVDGFGFDDFAFDFFGGFGFFGGDDFFFXAAFDGVDDAAADAGGFDFGGVDXAFGGGVDGFADAGDGVFDDGXDVXGGGDDGGVDFFFFXFVAFGDGGGDDFGGDVFGXAAFDFFDFGFFGDFDFADFXFGDDXVAXXGGGFDAFFGGFFXDAFGGFFVGFAFGDFGXGAFXGGAFXDFDVGFDAGGFGADGGGXAAVDVDFFAVGGGGDFAVADGFVFDFDGFGGDDFVFVFFGFFGXDFFDFAGVGGDGDFDGFVDVDFGFFFGVVDVFFGVFFFDDGFFGAFGVAXGFADDDVGADDDAFVXDVGFFFFFGDDFDFFADAXGDDGXFAFGAAXDAGVGFFGFDD"
# Taille du code
code_size = 4
# Hauteur du tableau de permutations
array_height = len(cipher) // code_size
# Création du tableau
array = []
for x in range(code_size):
array.append([])
for y in range(array_height):
array[x].append(cipher[x*array_height + y])
# Pour chaque permutations possibles
for perm in permutations([0, 1, 2, 3], 4):
# Réarrangement du tableau
permuted_array = [array[i] for i in perm]
# Récupération des lettres 2 à 2 de gauche à droite puis haut en bas
groups = []
for y in range(array_height):
for x in range(0, code_size, 2):
groups.append(f"{permuted_array[x][y]}{permuted_array[x+1][y]}")
def decode_perm(text, groups):
# Pour chaque lettre du texte
for i in range(len(text)):
# Le groupe qui correspond à l'emplacement
replace_groups = groups[i]
# Remplacer par
replace_with = text[i]
# Si le groupe est déjà remplacé et ne correspond pas à la lettre au même emplacement
if len(replace_groups) == 1 and replace_groups != replace_with:
return None
# Remplacement de tous les groupes identiques
for j in range(len(groups)):
if groups[j] == replace_groups:
groups[j] = replace_with
# Concaténation de toutes les lettres en string
return groups