Le chiffrement VIC est l'un des chiffrements pour crayons et papiers les plus compliqués jamais conçus. Utilisé dans les années 1950 par l'espion soviétique Reino Häyhänen, surnommé "VICTOR", son principe principal est la sécurité grâce à l'obscurcissement; un grand nombre de faux - fuyants.
Votre tâche consiste à écrire un programme ou une fonction qui prendra un message et le codera à l'aide du chiffrement VIC. J'ai également posté un défi de décodeur de chiffrement VIC ici . Si l'une des instructions suivantes n'est pas claire, n'hésitez pas à vous renseigner à leur sujet dans les commentaires. Les instructions sont adaptées de ce site .
Encodage du chiffrement VIC
Préparation
Vous aurez besoin de cinq entrées:
- le message en clair
- un mot-clé court ou une phrase contenant les lettres les plus courantes dans votre langue
- une phrase clé, comme une citation ou une ligne d'une chanson (au moins 20 caractères)
- une date (ou un autre nombre composé de six chiffres ou plus)
- un numéro d'agent personnel
En pratique, ces quatre derniers doivent être convenus au préalable par l'expéditeur et le destinataire, y compris si le numéro d'agent de l'expéditeur ou du destinataire est utilisé pour le codage.
Mon exemple de message sera: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.
Nous encoderons en anglais (bien que vous puissiez utiliser la langue et l'alphabet que vous préférez) et les lettres les plus courantes de l'alphabet anglais sont A, E, I, N, O, R, S, T
. Je vais utiliser le mot-clé SENATORI
.
Ma phrase clé est une citation de Richard Feynman: "Le premier principe est que vous ne devez pas vous tromper - et vous êtes la personne la plus facile à tromper."
Comme date, je vais utiliser le 31 juillet 2016 (dans le format 3172016
), qui est le jour où j'ai écrit cette description.
Le numéro personnel que j'ai choisi est 9
.
Résumé des étapes
- Dérivez les clés intermédiaires à utiliser dans les étapes suivantes.
- Construisez et appliquez le damier chevauchant.
- Construisez et appliquez la première table de transposition.
- Construisez et appliquez la deuxième table de transposition (interrompue).
- Finalisez le message en insérant le groupe d'indicateurs de message.
Sous-mécanismes
Deux autres choses à expliquer avant d'entrer dans le vif du sujet: les processus d'addition de chaîne et de séquentialisation.
L'addition de chaîne, également connue sous le nom de générateur de Fibonacci décalé, fonctionne en prenant une séquence de chiffres de départ, en ajoutant les deux premiers chiffres sans les transporter (les additionner ensuite mod 10
) et en ajoutant le résultat à la fin. Par exemple:
79081
7 + 9 = 6
790816
9 + 0 = 9
7908169
0 + 8 = 8
79081698
8 + 1 = 9
790816989
1 + 6 = 7
7908169897
... and so on
La séquentialisation consiste essentiellement à prendre une séquence de lettres ou de chiffres et à les étiqueter par ordre alphabétique / numérique. Les doublons sont étiquetés de gauche à droite. Par exemple:
E X A M P L E
0 # A
1 0 2 # Es
1 0 3 2 # L
1 0 4 3 2 # M
1 0 4 5 3 2 # P
1 6 0 4 5 3 2 # X
3 3 0 5 8 4 2 0 4 7 5 4 8 1
0 1 # 0s
0 1 2 # 1
0 3 1 2 # 2
4 5 0 3 1 2 # 3s
4 5 0 6 3 1 7 8 2 # 4s
4 5 0 9 6 3 1 7 10 8 2 # 5s
4 5 0 9 6 3 1 7 11 10 8 2 # 7
4 5 0 9 12 6 3 1 7 11 10 8 13 2 # 8s
J'utilise l'indexation zéro ici, mais indexez comme vous le souhaitez.
1. Clés intermédiaires
Divisez les 20 premières lettres de la phrase clé en deux groupes de 10 et séquentiellement chacune individuellement, que nous appellerons S1
et S2
.
THEFIRSTPR
S1: 8201357946
INCIPLEIST
S2: 2603751489
Choisissez un identifiant de message aléatoire à 5 chiffres M
(cela peut être l'une des entrées si vous préférez):
M = 47921
Soustraire, sans emprunter (soustraire mod 10
), les cinq premiers chiffres de la date clé 3172016
de M
:
M 47921
date - 31720
= 16201
Ajoutez le résultat jusqu'à ce que vous ayez dix chiffres:
1620178218
Ajoutez ces chiffres à S1
, sans porter ou mod 10
, pour obtenir G
:
1620178218
S1 + 8201357946
G = 9821425154
Ci S2
- dessus , écrivez la séquence 0123456789. Localisez chaque chiffre de G
dans la séquence 0123456789 et remplacez-le par le chiffre directement en dessous S2
. Le résultat est T
.
0123456789
S2 2603751489
G 9821425154
T 9806705657
Utilisez l'ajout de chaîne pour passer T
à 60 chiffres.
9806705657
becomes
980670565778637511245490262369939288595822106344304316978734
Ces 50 derniers chiffres, en cinq rangées de dix chiffres chacune, forment le U
bloc.
T 9806705657
U 7863751124
5490262369
9392885958
2210634430
4316978734
Les deux derniers chiffres non égaux du U
bloc sont ajoutés individuellement au numéro personnel de l'agent pour donner les largeurs des deux transpositions, p
et q
.
9 + 3 = 12 (p, première largeur de transposition) 9 + 4 = 13 (q, deuxième largeur de transposition)
Séquentialiser T
et utiliser cette séquence pour copier au large des colonnes du U
bloc, de haut en bas, dans une nouvelle rangée de caractères, V
.
T 9806705657
seqT 9804612537
U 7863751124
5490262369
9392885958
2210634430
4316978734
V 69911 56837 12548 26533 30206 13947 72869 49804 84323 75924
Séquentialisez les premiers p
chiffres pour obtenir la clé de la première transposition K1
et les q
chiffres suivants pour la clé de la seconde K2
.
First 12 6 9 9 1 1 5 6 8 3 7 1 2
K1 6 10 11 0 1 5 7 9 4 8 2 3
Next 13 5 4 8 2 6 5 3 3 3 0 2 0 6
K2 8 7 12 2 10 9 4 5 6 0 3 1 11
Enfin, séquentialisez la dernière ligne du U
bloc à obtenir C
, les en-têtes de colonne pour le damier chevauchant:
U5 4316978734
C 3105968724
2. Damier chevauchant
Tout d'abord, je vais donner mon exemple de damier, puis expliquer les principes de sa création de cette manière:
3 1 0 5 9 6 8 7 2 4
S E N A T O R I
2 B D G J L P U W Y .
4 C F H K M Q V X Z #
La première ligne de lettres est notre court mot - clé SENATORI
. Votre mot-clé peut être n'importe quelle chaîne sans doublons, mais comme il définit la ligne supérieure de votre damier, choisissez judicieusement. Au-dessus du mot-clé se trouve C
, et les autres lignes sont le reste de votre alphabet dans l'ordre que vous choisissez. Dans mon cas, j'ai rempli le damier avec le reste de l'alphabet latin, un signe de ponctuation .
et un signe de démarcation des nombres #
. Essentiellement, le damier est un chiffrement de substitution sophistiqué. Par exemple, "E" sera remplacé par 1
et "W" sera remplacé par 27
.
Une fois que nous avons encodé notre message en clair avec ce damier, mais d'abord, nous devons rendre le début de notre message moins évident en le divisant à une position aléatoire et en le rendant tout en majuscules. Pour désigner l'autre début d'origine, nous utilisons deux arrêts complets..
We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.
devient
HING ELSE. MOVE TO SAFEHOUSE FOXTROT#3#.. WE ARE
DISCOVERED. TAKE WHAT YOU CAN. BURN EVERYT
Nous encodons avec le damier, nous donnant:
407020 1293124 496481 96 354114062831 416479869443442424 271 581
2173436481812124 95451 274059 22628 435024 232880 14818229
Si la longueur du message n'est pas divisible par 5, nous ajoutons quelques caractères nuls pour compléter le message. Notre message comporte 109 chiffres, je vais donc ajouter un null: "4".
40702 01293 12449 64819 63541 14062 83141 64798 69443 44242 42715
81217 34364 81812 12495 45127 40592 26284 35024 23288 01481 82294
Remarque: Étant donné que mon exemple de message ne contient pas de chiffres, je dirai ici que vous pouvez désigner, disons, as #3#
, qui est codé comme 44344
ici.
3. Première transposition
Créez la table de transposition en écrivant K1
(à partir de la section Clés intermédiaires) suivi du message codé de l'étape précédente, en lignes de même longueur, sous la clé:
K1 6 10 11 0 1 5 7 9 4 8 2 3
4 0 7 0 2 0 1 2 9 3 1 2
4 4 9 6 4 8 1 9 6 3 5 4
1 1 4 0 6 2 8 3 1 4 1 6
4 7 9 8 6 9 4 4 3 4 4 2
4 2 4 2 7 1 5 8 1 2 1 7
3 4 3 6 4 8 1 8 1 2 1 2
4 9 5 4 5 1 2 7 4 0 5 9
2 2 6 2 8 4 3 5 0 2 4 2
3 2 8 8 0 1 4 8 1 8 2 2
9 4
En prenant les colonnes numérotées dans l'ordre de leur nombre, nous obtenons:
060826428 246674580 151411542 246272922 961311401 082918141
4414434239 118451234 334422028 293488758 0417249224 794943568
4. Deuxième transposition
La première transposition a été relativement simple. Celui-ci, cependant, est une transposition perturbée. Le motif de perturbation est déterminé par la largeur de la table et de la clé. Dans notre exemple, nous avons 110 chiffres et 13 colonnes, ce qui signifie que nous aurons 8 lignes complètes et 6 restes. Nous commençons à remplir la première ligne, mais nous nous arrêtons à la colonne 0 et continuons comme suit:
K2 8 7 12 2 10 9 4 5 6 0 3 1 11
0 6 0 8 2 6 4 2 8 stop at 0
2 4 6 6 7 4 5 8 0 1 continue in a triangle pattern
5 1 4 1 1 5 4 2 2 4 6
2 7 2 9 2 2 9 6 1 3 1 1
4 0 1 0 8 2 9 1 8 1 4 1 4 until the end
4 1 4 4 3 4 2 3 9 1 1 restart and stop at 1
8 4 5 1 2 3 4 3 3 4 4 2
2 0 2 8 2 9 3 4 8 8 7 5 8
0 4 1 restart and stop at 2
Ensuite, nous remplissons les derniers espaces avec les chiffres restants.
K2 8 7 12 2 10 9 4 5 6 0 3 1 11
0 6 0 8 2 6 4 2 8 7 2 4 9
2 4 6 6 7 4 5 8 0 1 2 2 4
5 1 4 1 1 5 4 2 2 4 6 7 9
2 7 2 9 2 2 9 6 1 3 1 1 4
4 0 1 0 8 2 9 1 8 1 4 1 4
4 1 4 4 3 4 2 3 9 1 1 9 4
8 4 5 1 2 3 4 3 3 4 4 2 3
2 0 2 8 2 9 3 4 8 8 7 5 8
0 4 1 5 6 8
Maintenant, nous lisons les colonnes exactement de la même manière que pour la première transposition.
71431148 42711925 861904185 22614147 45499243 28261334 80218938
641701404 025244820 645224398 271283226 94944438 064214521
Et divisez tout en groupes à 5 chiffres:
71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189
38641 70140 40252 44820 64522 43982 71283 22694 94443 80642 14521
5. Finalisez le message
La dernière étape consiste à insérer notre identifiant de message aléatoire,, 47921
dans le message lui-même. Le dernier chiffre de la date clé 6
indique la distance que le groupe doit être de la fin.
71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189 38641
70140 40252 44820 64522 43982 47921 71283 22694 94443 80642 14521
Notes pour ce défi
- Vous disposez d'au moins cinq entrées: le message, le mot clé de la lettre, la phrase clé, la date et un numéro personnel. Vous pouvez inclure deux entrées supplémentaires: l'identificateur de message aléatoire et les valeurs nulles nécessaires pour remplir le message, ou votre fonction peut générer des nombres aléatoires d'elle-même.
- Vous pouvez supposer que toutes les entrées sont valides, avec le nombre correct de chiffres et de lettres (identifiant de message à 5 chiffres, au moins 20 chiffres pour la phrase clé, etc.). Vous pouvez supposer que toutes les ponctuations et tous les espaces ont déjà été supprimés, à l'exception de ceux que vous autorisez dans votre version, et que les nombres sont déjà délimités par des signes numériques.
- Le premier mot clé ne doit pas contenir de lettres en double, et dans votre code, vous pouvez supposer qu'il n'a jamais de lettres en double.
- La langue que vous utilisez pour encoder n'a pas d'importance, tant que la langue est préexistante, l'alphabet est préexistant et que vous spécifiez la langue que vous utilisez dans votre réponse.
- Quel que soit l'alphabet que vous employez pour votre damier chevauchant, vous pouvez ajouter ou supprimer des symboles pour remplir le damier. Spécifiez la raison pour laquelle vous utilisez ces symboles (par exemple, la ponctuation, un symbole distinct de «début de message», des symboles de mots courants). Vous pouvez renoncer entièrement au signe numérique et épeler les chiffres ou inclure chaque chiffre dans le damier, en utilisant la fente où le signe numérique était pour autre chose. Veuillez préciser quel damier vous avez utilisé dans votre réponse.
- La sortie doit être soit une chaîne de groupes à cinq chiffres séparés par des espaces, une liste d'entiers à cinq chiffres, ou quelque chose de similaire.
- J'ai utilisé l'indexation zéro et
0123456789
dans mon exemple. Vous pouvez utiliser l'indexation 1 et1234567890
, ou un autre système dans votre réponse, tant que vous spécifiez ce que vous avez utilisé.
Voici un exemple d'implémentation sur Ideone .
Ceci est un long post et j'ai écrit la plupart à la main, donc s'il y a des parties confuses dans ce post ou des erreurs dans mon comptage et ma transposition, veuillez me le faire savoir. Bonne chance et bon golf!
la source
adding the first two digits without adding
Voulez-vous dire porter?without borrowing
etwithout carrying
? Voulez-vous dire ajouter et soustraire le mod10
, c'est(6+7) mod 10 = 3
-à- dire et(6-8) mod 10 = 8
?Réponses:
Python 3 ,
14231348132413161300128612501249120912061204 octetsC'est certainement le plus long golf que j'ai jamais fait, et le seul golf où je craignais sérieusement de manquer de noms de variable à un caractère. Suggestions de golf bienvenues. Essayez-le en ligne!
J'encode avec l'alphabet latin majuscule avec des caractères supplémentaires
.
et#
, en utilisant l'indexation 0 et0123456789
lors de la conversiong
ent
. Mon damier est dans un format similaire à l'exemple suivant:Edit: -63 octets grâce à la suggestion de TuukkaX de raccourcir certaines des fonctions fréquemment utilisées avec des variables à une lettre. -12 octets de rendre
a, g, t
plus compact.Modifier: -24 octets de création en supprimant les noms de variables pour les clés intermédiaires qui ne sont utilisées qu'une seule fois, à savoir
a, g, s, S, k, K
.Edit: -74 octets de consolidation
H(), T() and C()
.Edit: -1 octet merci à Nick A pour sa suggestion de changer
ord(s[i])+ord(s[i+1])
ensum(map(ord,s[i:i+2]))
. -2 octets de la modification de 2+=[a]
appels à+=a,
. -13 octets de changer la façon dont aG()
trouvé l'indice du minimum des
. -2 octets de passery=(y+1)%v
ày=-~y%v
. -15 octets d'affectationk.index()
àK
. -4 octets d'attribution10
àW
. -5 octets d'affectation1-I(d[-1])
à l'X
intérieurV
. -3 octets deC()
la boucle principale de réécriture . -2 octets de réorganisationT()
.Ungolfing:
la source
ord(seq[i])+ord(seq[i+1])
poursum(map(ord,seq[i:i+2]))
sauver 1 personnage je crois.C,
288027692766276227432741273926992458 octetsMon Dieu. C'est le programme le plus long que j'ai jamais eu au golf. C'est également le premier sur lequel j'ai en fait manqué de noms de variables à un seul caractère pour la portée globale et j'ai donc dû passer à l'utilisation de quelques caractères à 2 caractères (le fait que je ne peux apparemment pas redéclarer les variables n'aide pas). Les conseils de golf sont donc très appréciés.
Non golfé
Compile sans aucun avertissement, contrairement à la version golfée. Les modifications mineures apportées à la version golfée ne seront pas reflétées dans cette version non golfée.
Remarques
Cela utilise un damier semblable au suivant pour coder le message:
Cela suppose que toutes les chaînes applicables sont données en majuscules. Le message doit également avoir toute la ponctuation sauf les périodes supprimées et tous les nombres délimités par
#
s, tandis que la phrase clé doit avoir supprimé toute la ponctuation.Le message codé résultant est envoyé à STDOUT sous la forme d'une chaîne de groupes à cinq chiffres séparés par des espaces.
Le message d'entrée doit être en anglais.
J'aurais combiné quelques-unes des fonctions que j'ai utilisées, mais je devrais alors recourir à plus de noms de variables à deux lettres, ce qui rend le programme final plus long qu'il ne le serait avec quelques fonctions supplémentaires.
Actuellement, cela ne suppose pas que le mot-clé (au moins en anglais) contiendra toujours le même ensemble de lettres, et compense donc cela en supprimant les doublons, en manipulant le damier, etc. Cette capacité n'est apparemment pas requise par OP, donc je joue actuellement sur les octets supplémentaires inutiles qui prennent.Mis à jour pour la version golfée.la source
JavaScript (ES6),
946938953 octetsJ'ai vu au cours du week-end qu'il n'y avait pas encore d'entrée JS pour cela, alors voici ma tentative (de dernière minute). Mettre en œuvre et jouer au golf était aussi fou que amusant!
Extrait de démonstration
Afficher l'extrait de code
Modifier: -8 octets
Réalisé qu'il y avait des parenthèses supplémentaires autour de la fonction
S,J,A,Q
Modifier: +15 octets
Mise à jour de la logique de la façon dont le
message id
est placé dans le message final (désormais indexé 1 et 0 ne l'inclut pas dans la sortie).Non golfé
Remarques
Cela utilise un damier semblable au suivant pour coder le message:
Toutes les chaînes sont données en majuscules. Le message est en latin alphanumérique (plus
.
et#
) et doit avoir supprimé toute ponctuation (sauf les points). Tous les numéros doivent déjà être marqués de l'#
art. La phrase clé doit avoir supprimé tous les signes de ponctuation / espaces.Le message résultant est renvoyé sous la forme d'un tableau de chaînes à 5 chiffres.
Améliorations
J'ai l'impression qu'il existe un moyen d'abuser des "Toutes les langues" pour économiser quelques octets. Si j'avais plus de temps, je refigurerais cela pour supposer que la langue était quelque chose comme le hawaïen qui n'a que 12 lettres.
Toutes les suggestions de golf sont toujours les bienvenues.
la source
message identifier
semble être7
loin de la fin au lieu de6
. De plus, dans votre version non golfée, la même choseId
semble être6
loin du début plutôt que de la fin.1
signifie la toute fin, où diriez-vous que lemessage identifier
devrait aller sur un0
? Je peux le changer, j'ai juste besoin de le savoir.0
lamessage identifier
devrait être exclue de la sortie.Clojure,
11971212 octetsOugh, je suis épuisé.
Mise à jour: ajout de l'emplacement de fractionnement aléatoire requis du message, la version non golfée utilise le même emplacement que l'exemple donné afin que l'algorithme puisse être facilement vérifié.
Exemples d'entrées et scénario de test:
Non golfé:
Il a une implémentation alternative sur le damier
B
qui est la même que sur la définition de la tâche. Mais la soumission en utilise une autre dans laquelle les alphabets inutilisés remplissent d'abord la 2e ligne, puis la 3e au lieu de remplir colonne par colonne.la source
coords
est généré deux fois, générant d'abord la forme triangulaire, puis remplissant toutes les coordonnées manquantes. «Remplissage à la longueur de la multiplication de N» pourrait également avoir une solution plus élégante que la concaténation des éléments N-1 et le partitionnement aux longueurs de N.(split-at 49 mymsg)
, 49 devrait être quelque chose comme(rand-int(count mymsg))
si la bonne réponse serait un peu plus de 1200 octets. zzz