Die VIC-Chiffre ist eine der kompliziertesten Bleistift- und Papier-Chiffren, die jemals erfunden wurden. In den 1950er Jahren von dem sowjetischen Spion Reino Häyhänen mit dem Codenamen "VICTOR" eingesetzt, ist sein Hauptprinzip Sicherheit durch Verschleierung; eine Menge von Verschleierung.
Ihre Aufgabe ist es, ein Programm oder eine Funktion zu schreiben, die eine Nachricht aufnimmt und sie mit der VIC-Verschlüsselung verschlüsselt. Ich habe auch eine VIC-Verschlüsselungs-Decoder-Herausforderung hier gepostet . Wenn eine der folgenden Anweisungen unklar ist, zögern Sie nicht, sie in den Kommentaren nachzufragen. Die Anleitung ist von dieser Seite angepasst .
Codierung der VIC-Chiffre
Vorbereitung
Sie benötigen fünf Eingänge:
- die Klartextnachricht
- ein kurzes Schlüsselwort oder eine kurze Phrase, die die häufigsten Buchstaben in Ihrer Sprache enthält
- eine Schlüsselphrase, z. B. ein Zitat oder eine Zeile aus einem Lied (mindestens 20 Zeichen)
- ein Datum (oder eine andere Zahl mit sechs oder mehr Ziffern)
- eine persönliche Agentennummer
In der Praxis sollten die letzten vier vom Absender und vom Empfänger im Voraus vereinbart werden, einschließlich der Angabe, ob die Agentennummer des Absenders oder des Empfängers für die Codierung verwendet wird.
Meine Beispielnachricht lautet: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.
Wir codieren in Englisch (Sie können jedoch jede Sprache und jedes Alphabet verwenden, die Sie bevorzugen), und die häufigsten Buchstaben im englischen Alphabet sind A, E, I, N, O, R, S, T
. Ich werde das Schlüsselwort verwenden SENATORI
.
Mein Schlüsselbegriff ist ein Zitat von Richard Feynman: "Das erste Prinzip ist, dass Sie sich nicht selbst zum Narren halten dürfen - und Sie sind die am einfachsten zu täuschene Person."
Als Datum verwende ich den 31. Juli 2016 (im Format 3172016
). Dies ist der Tag, an dem ich diese Beschreibung geschrieben habe.
Die persönliche Nummer, die ich für mich gewählt habe, ist 9
.
Zusammenfassung der Schritte
- Leiten Sie die Zwischenschlüssel für die folgenden Schritte ab.
- Konstruieren Sie das Schachbrett und bringen Sie es an.
- Erstellen Sie die erste Umsetzungstabelle und wenden Sie sie an.
- Erstellen Sie die zweite (unterbrochene) Umsetzungstabelle und wenden Sie sie an.
- Schließen Sie die Nachricht ab, indem Sie die Nachrichtenanzeigegruppe einfügen.
Submechanismen
Zwei weitere Dinge, die erklärt werden müssen, bevor wir auf das Wesentliche eingehen: die Prozesse der Kettenaddition und der Sequenzierung.
Die Kettenaddition, die auch als verzögerter Fibonacci-Generator bezeichnet wird, verwendet eine Startziffernfolge, addiert die ersten beiden Ziffern, ohne sie zu tragen (addieren Sie sie dann mod 10
), und hängt das Ergebnis an das Ende an. Beispielsweise:
79081
7 + 9 = 6
790816
9 + 0 = 9
7908169
0 + 8 = 8
79081698
8 + 1 = 9
790816989
1 + 6 = 7
7908169897
... and so on
Bei der Sequenzierung werden im Wesentlichen Buchstaben oder Ziffern nach ihrer alphabetischen / numerischen Reihenfolge sortiert. Duplikate sind von links nach rechts beschriftet. Beispielsweise:
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
Ich verwende hier die Null-Indizierung, indiziere aber, wie Sie möchten.
1. Zwischentasten
Teilen Sie die ersten 20 Buchstaben des Schlüsselphrase in zwei Gruppen von 10 und sequentialisieren jeweils einzeln, die wir nennen S1
und S2
.
THEFIRSTPR
S1: 8201357946
INCIPLEIST
S2: 2603751489
Wählen Sie eine zufällige 5-stellige Nachrichtenkennung M
(dies kann eine der Eingaben sein, wenn Sie dies vorziehen):
M = 47921
Ohne Ausleihen (subtrahieren mod 10
) subtrahieren Sie die ersten fünf Stellen des Stichtags 3172016
von M
:
M 47921
date - 31720
= 16201
Kette addiere das Ergebnis, bis du zehn Ziffern hast:
1620178218
Addieren Sie diese Ziffern S1
, ohne oder mod 10
zu tragen , um Folgendes zu erhalten G
:
1620178218
S1 + 8201357946
G = 9821425154
Oben S2
, schreiben 0123456789. die Sequenz liegt jede Ziffer von G
in der Folge 0123456789 und mit der direkt darunter in Ziffer ersetzen S2
. Das Ergebnis ist T
.
0123456789
S2 2603751489
G 9821425154
T 9806705657
Verwenden Sie die Kettenaddition, um T
auf 60 Stellen zu erweitern .
9806705657
becomes
980670565778637511245490262369939288595822106344304316978734
Diese letzten 50 Ziffern bilden in fünf Zeilen zu je zehn Ziffern den U
Block.
T 9806705657
U 7863751124
5490262369
9392885958
2210634430
4316978734
Die letzten beiden ungleichen Ziffern des U
Blocks werden einzeln zur persönlichen Nummer des Agenten addiert, um die Breite der beiden Transpositionen p
und anzugeben q
.
9 + 3 = 12 (p, erste Transpositionsbreite) 9 + 4 = 13 (q, zweite Transpositionsbreite)
Sequenzieren T
und verwenden Sie diese Sequenz, um die Spalten des U
Blocks von oben nach unten in eine neue Ziffernreihe zu kopieren V
.
T 9806705657
seqT 9804612537
U 7863751124
5490262369
9392885958
2210634430
4316978734
V 69911 56837 12548 26533 30206 13947 72869 49804 84323 75924
Sequenziellisieren Sie die ersten p
Ziffern, um die Tonart für die erste Transposition K1
und die folgenden q
Ziffern für die Tonart für die zweite zu erhalten 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
Zuletzt die letzte Zeile des U
Blocks sequentiell anordnen, um C
die Spaltenüberschriften für das überspannende Schachbrett zu erhalten:
U5 4316978734
C 3105968724
2. Auf dem Schachbrett spreizen
Zuerst gebe ich mein Beispiel-Schachbrett und erkläre dann die Prinzipien, wie man es auf diese Weise erstellt:
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 #
Die erste Buchstabenzeile ist unser kurzes Stichwort SENATORI
. Ihr Schlüsselwort kann eine beliebige Zeichenfolge ohne Duplikate sein. Wählen Sie jedoch mit Bedacht aus, da sie die oberste Zeile Ihres Schachbretts definiert. Über dem Schlüsselwort steht C
und die anderen Zeilen sind der Rest Ihres Alphabets in der von Ihnen gewählten Reihenfolge. In meinem Fall füllte ich das Schachbrett mit dem Rest des lateinischen Alphabets, einem Satzzeichen .
und einem Zeichen zur Abgrenzung von Zahlen #
. Im Grunde ist das Schachbrett eine ausgefallene Ersatzchiffre. Beispielsweise wird "E" durch 1
"W" ersetzt 27
.
Nachdem wir unsere Klartextnachricht mit diesem Schachbrett kodiert haben, müssen wir zunächst den Anfang unserer Nachricht weniger deutlich machen, indem wir sie an einer zufälligen Position aufteilen und in Großbuchstaben schreiben. Um den anderen ursprünglichen Anfang zu kennzeichnen, verwenden wir zwei Punkte..
We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.
wird
HING ELSE. MOVE TO SAFEHOUSE FOXTROT#3#.. WE ARE
DISCOVERED. TAKE WHAT YOU CAN. BURN EVERYT
Wir kodieren mit dem Schachbrett und geben uns:
407020 1293124 496481 96 354114062831 416479869443442424 271 581
2173436481812124 95451 274059 22628 435024 232880 14818229
Wenn die Länge der Nachricht nicht durch 5 teilbar ist, fügen wir einige Nullzeichen hinzu, um die Nachricht aufzufüllen. Unsere Nachricht ist 109-stellig, daher füge ich eine Null hinzu: "4".
40702 01293 12449 64819 63541 14062 83141 64798 69443 44242 42715
81217 34364 81812 12495 45127 40592 26284 35024 23288 01481 82294
Hinweis: Da meine Beispielnachricht keine Zahlen enthält, sage ich hier, dass Sie sagen könnten, als #3#
, was wie 44344
hier codiert ist.
3. Erste Umsetzung
Erstellen Sie die Transpositionstabelle, indem Sie K1
(aus dem Abschnitt "Intermediate Keys") gefolgt von der codierten Nachricht aus dem vorherigen Schritt in gleich langen Zeilen unter den Schlüssel schreiben :
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
Nimmt man die nummerierten Spalten in der Reihenfolge ihrer Nummern, so erhält man:
060826428 246674580 151411542 246272922 961311401 082918141
4414434239 118451234 334422028 293488758 0417249224 794943568
4. Zweite Umsetzung
Die erste Umsetzung war relativ einfach. Dies ist jedoch eine gestörte Umsetzung. Das Unterbrechungsmuster wird durch die Breite des Tisches und des Schlüssels bestimmt. In unserem Beispiel haben wir 110 Stellen und 13 Spalten, dh wir haben 8 volle Zeilen und 6 Reste. Wir beginnen mit dem Ausfüllen der ersten Zeile, hören aber bei Spalte 0 auf und fahren wie folgt fort:
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
Dann füllen wir die letzten Stellen mit den restlichen Ziffern.
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
Nun lesen wir die Spalten genauso ab, wie wir es bei der ersten Umsetzung getan haben.
71431148 42711925 861904185 22614147 45499243 28261334 80218938
641701404 025244820 645224398 271283226 94944438 064214521
Und alles in 5-stellige Gruppen aufteilen:
71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189
38641 70140 40252 44820 64522 43982 71283 22694 94443 80642 14521
5. Finalisieren Sie die Nachricht
Der letzte Schritt besteht darin, unsere zufällige Nachrichten-ID 47921
in die Nachricht selbst einzufügen . Die letzte Ziffer des Stichtags 6
gibt an, wie weit die Gruppe vom Ende entfernt sein sollte.
71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189 38641
70140 40252 44820 64522 43982 47921 71283 22694 94443 80642 14521
Notizen für diese Herausforderung
- Sie erhalten mindestens fünf Eingaben: die Nachricht, das Buchstabenschlüsselwort, die Schlüsselphrase, das Datum und eine persönliche Nummer. Sie können zwei zusätzliche Eingaben einschließen: die Zufallsnachrichtenkennung und die Nullen, die zum Ausfüllen der Nachricht erforderlich sind, oder Ihre Funktion generiert möglicherweise selbst Zufallszahlen.
- Sie können davon ausgehen, dass alle Eingaben gültig sind, mit der richtigen Anzahl von Ziffern und Buchstaben (5-stellige Nachrichtenkennung, mindestens 20 Ziffern für die Schlüsselphrase usw.). Sie können davon ausgehen, dass in Ihren Zeichenfolgen (der Nachricht und den Schlüsselwörtern) bereits alle Satzzeichen und Leerzeichen entfernt wurden, mit Ausnahme derjenigen, die Sie in Ihrer Version zulassen, und dass Zahlen bereits durch Nummernzeichen abgegrenzt sind.
- Das erste Schlüsselwort sollte keine doppelten Buchstaben enthalten, und Sie können davon ausgehen, dass es in Ihrem Code niemals doppelte Buchstaben enthält.
- Die Sprache, in der Sie codieren, spielt keine Rolle, solange die Sprache bereits vorhanden ist, das Alphabet bereits vorhanden ist und Sie angeben, welche Sprache Sie in Ihrer Antwort verwenden.
- Unabhängig davon, welches Alphabet Sie für Ihr Schachbrett verwenden, können Sie Symbole hinzufügen oder entfernen, um das Schachbrett aufzufüllen. Geben Sie an, wofür Sie diese Symbole verwenden (z. B. Satzzeichen, ein separates Symbol für "Nachrichtenbeginn", Symbole für gebräuchliche Wörter). Sie können ganz auf das Nummernzeichen verzichten und die Nummern buchstabieren oder jede Ziffer in das Schachbrett einfügen, indem Sie den Schlitz verwenden, in dem sich das Nummernzeichen für etwas anderes befand. Bitte geben Sie an, welches Schachbrett Sie in Ihrer Antwort verwendet haben.
- Die Ausgabe sollte entweder eine Folge von durch Leerzeichen getrennten fünfstelligen Gruppen, eine Liste von fünfstelligen ganzen Zahlen oder etwas Ähnliches sein.
- Ich habe
0123456789
in meinem Beispiel die Null-Indexierung verwendet . Sie können 1-Indizierung und1234567890
oder ein anderes System in Ihrer Antwort verwenden, solange Sie angeben, was Sie verwendet haben.
Hier ist eine Beispielimplementierung für Ideone .
Dies ist ein langer Beitrag, den ich größtenteils von Hand geschrieben habe. Sollten Sie also verwirrende Teile in diesem Beitrag oder Fehler beim Zählen und Transponieren bemerken, lassen Sie es mich bitte wissen. Viel Glück und gutes Golfen!
quelle
adding the first two digits without adding
Meinst du tragen?without borrowing
und meinenwithout carrying
? Meinst du addieren und subtrahieren mod10
, dh(6+7) mod 10 = 3
und(6-8) mod 10 = 8
?Antworten:
Python 3 ,
14231348132413161300128612501249120912061204 BytesDies ist definitiv das längste Golf, das ich je gemacht habe, und das einzige Golf, bei dem ich ernsthafte Bedenken hatte, dass mir die Variablennamen mit einem Zeichen ausgehen könnten. Golfvorschläge sind willkommen. Probieren Sie es online!
Ich codiere mit dem lateinischen Großbuchstaben mit zusätzlichen Zeichen
.
und#
verwende 0-Indexierung und0123456789
beim Konvertiereng
int
. Mein Schachbrett hat ein Format ähnlich dem folgenden Beispiel:Edit: -63 Bytes dank des Vorschlags von TuukkaX, einige der häufig verwendeten Funktionen mit Ein-Buchstaben-Variablen zu kürzen. -12 Bytes aus
a, g, t
kompakter zu machen.Bearbeiten: -24 Bytes durch Entfernen von Variablennamen für Zwischenschlüssel, die nur einmal verwendet werden, nämlich
a, g, s, S, k, K
.Edit: -74 Bytes von der Konsolidierung
H(), T() and C()
.Edit: -1 Byte dank Nick A für ihren Vorschlag ändern
ord(s[i])+ord(s[i+1])
zusum(map(ord,s[i:i+2]))
. -2 Bytes vom Ändern von 2+=[a]
Aufrufen nach+=a,
. -13 Bytes aus der Änderung, wieG()
der Index des Minimums von gefundens
. -2 Bytes vom Änderny=(y+1)%v
zuy=-~y%v
. -15 Bytes von der Zuweisungk.index()
anK
. -4 Bytes von der Zuweisung10
anW
. -5 Bytes von der Zuweisung1-I(d[-1])
anX
innenV
. -3 Bytes vonC()
der Hauptschleife des Umschreibens . -2 Bytes von ReorganisationT()
.Ungolfing:
quelle
ord(seq[i])+ord(seq[i+1])
umsum(map(ord,seq[i:i+2]))
1 Charakter zu speichern, glaube ich.C
288027692766276227432741273926992458 BytesMeine Güte. Dies ist das längste Programm, das ich habe jemals zum Golfen hatte. Dies ist auch das erste Mal, dass ich für den globalen Gültigkeitsbereich keine einzelnen Variablennamen mehr habe und daher ein paar 2-stellige verwenden muss (die Tatsache, dass ich anscheinend keine Variablen neu deklarieren kann, hilft nicht weiter). Golftipps werden daher sehr geschätzt.
Ungolfed
Kompiliert ohne Vorwarnung, im Gegensatz zur Golfversion. Geringfügige Änderungen an der Golfversion werden in dieser ungolften Version nicht berücksichtigt.
Anmerkungen
Hierbei wird ein Schachbrett verwendet, das der folgenden Abbildung ähnelt, um die Nachricht zu codieren:
Dies setzt voraus, dass alle zutreffenden Zeichenfolgen in Großbuchstaben angegeben werden. Die Nachricht sollte auch alle Satzzeichen enthalten, mit Ausnahme von entfernten Punkten und allen durch
#
s abgegrenzten Zahlen , während die Schlüsselphrase alle enthalten sollte Satzzeichen enthalten sollte.Die resultierende codierte Nachricht wird als Zeichenfolge von durch Leerzeichen getrennten fünfstelligen Gruppen an STDOUT ausgegeben.
Die Eingabenachricht sollte in Englisch sein.
Ich hätte einige der Funktionen, die ich verwendet habe, kombiniert, musste dann aber auf mehr aus zwei Buchstaben bestehende Variablennamen zurückgreifen, was das endgültige Programm länger machte als mit ein paar weiteren Funktionen.
Dies setzt derzeit nicht voraus, dass das Schlüsselwort (zumindest in englischer Sprache) immer den gleichen Satz von Buchstaben enthält, und gleicht dies durch Entfernen von Duplikaten, Manipulieren des Schachbretts usw. aus. Diese Funktion wird von OP anscheinend nicht benötigt. Also spiele ich gerade die zusätzlichen, unnötigen Bytes ab, die belegt werden.Aktualisiert für die Golfversion.quelle
JavaScript (ES6),
946938953 BytesIch habe über das Wochenende gesehen, dass es noch keinen JS-Eintrag für diesen gibt, also hier ist mein (Last-Minute-) Versuch. Das umzusetzen und zu golfen war genauso verrückt wie es Spaß gemacht hat!
Demo-Snippet
Code-Snippet anzeigen
Edit: -8 Bytes
Es wurde erkannt, dass es zusätzliche Klammern um die Funktion gibt
S,J,A,Q
Edit: +15 Bytes
Aktualisierte die Logik für, wie die
message id
Platzierung von in der endgültigen Nachricht wurde (jetzt 1-indiziert und 0 schließt sie nicht in die Ausgabe ein).Ungolfed
Anmerkungen
Hierbei wird ein Schachbrett verwendet, das der folgenden Abbildung ähnelt, um die Nachricht zu codieren:
Alle Zeichenfolgen werden in Großbuchstaben angegeben. Die Nachricht ist alphanumerisch lateinisch (plus
.
und#
) und sollte alle Satzzeichen (außer Punkte) entfernt haben. Alle Nummern sollten bereits mit#
s markiert sein . In der Schlüsselphrase sollten alle Satzzeichen / Leerzeichen entfernt sein.Die resultierende Nachricht wird als Array von 5-stelligen Zeichenfolgen zurückgegeben.
Verbesserungen
Ich habe das Gefühl, dass es einen Weg gibt, die "Alle Sprachen" zu missbrauchen, um ein paar Bytes zu sparen. Wenn ich mehr Zeit hätte, würde ich dies neu konfigurieren, um anzunehmen, dass die Sprache so etwas wie Hawaiianisch ist, das nur 12 Buchstaben hat.
Vorschläge zum Golfen sind immer willkommen.
quelle
message identifier
scheint das7
vom Ende weg zu sein6
. Auch in Ihrer ungolfed VersionId
scheint das gleiche6
vom Anfang weg zu sein, anstatt vom Ende.1
heißt, am Ende, wo würdest du sagen,message identifier
sollte das weitergehen0
? Ich kann es ändern, ich muss es nur wissen.0
dermessage identifier
sollte von der Ausgabe weggelassen werden.Clojure,
1197 -1212 BytesOh, ich bin erschöpft.
Update: Der erforderliche zufällige Aufteilungsort der Nachricht wurde hinzugefügt. In der ungolfed-Version wird derselbe Ort wie im angegebenen Beispiel verwendet, damit der Algorithmus leicht überprüft werden kann.
Beispieleingaben und Testfall:
Ungolfed:
Es gibt eine alternative Implementierung auf dem Schachbrett,
B
die mit der Definition der Aufgabe identisch ist. Die Übermittlung verwendet jedoch eine andere, bei der nicht verwendete Alphabete zuerst die zweite und dann die dritte Zeile ausfüllen, anstatt Spalte für Spalte auszufüllen.quelle
coords
wird nun zweimal generiert, indem zuerst die Dreiecksform generiert und dann alle fehlenden Koordinaten ausgefüllt werden. Auch "Auffüllen auf Länge multiplizieren mit N" könnte eine elegantere Lösung sein, als N - 1 Elemente zu verketten und auf Längen von N zu partitionieren.(split-at 49 mymsg)
, 49 sollte so etwas wie eine(rand-int(count mymsg))
richtige Antwort sein, die etwas über 1200 Bytes liegt. zzz