Schreiben Sie einen VIC-Verschlüsselungscodierer

18

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

  1. Leiten Sie die Zwischenschlüssel für die folgenden Schritte ab.
  2. Konstruieren Sie das Schachbrett und bringen Sie es an.
  3. Erstellen Sie die erste Umsetzungstabelle und wenden Sie sie an.
  4. Erstellen Sie die zweite (unterbrochene) Umsetzungstabelle und wenden Sie sie an.
  5. 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 S1und 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 3172016von M:

M      47921
date - 31720
     = 16201

Kette addiere das Ergebnis, bis du zehn Ziffern hast:

1620178218

Addieren Sie diese Ziffern S1, ohne oder mod 10zu tragen , um Folgendes zu erhalten G:

     1620178218
S1 + 8201357946
G  = 9821425154

Oben S2, schreiben 0123456789. die Sequenz liegt jede Ziffer von Gin 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 Tauf 60 Stellen zu erweitern .

9806705657

becomes

980670565778637511245490262369939288595822106344304316978734

Diese letzten 50 Ziffern bilden in fünf Zeilen zu je zehn Ziffern den UBlock.

T  9806705657
U  7863751124
   5490262369
   9392885958
   2210634430
   4316978734

Die letzten beiden ungleichen Ziffern des UBlocks werden einzeln zur persönlichen Nummer des Agenten addiert, um die Breite der beiden Transpositionen pund anzugeben q.

9 + 3 = 12 (p, erste Transpositionsbreite) 9 + 4 = 13 (q, zweite Transpositionsbreite)

Sequenzieren Tund verwenden Sie diese Sequenz, um die Spalten des UBlocks 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 pZiffern, um die Tonart für die erste Transposition K1und die folgenden qZiffern 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 UBlocks sequentiell anordnen, um Cdie 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 Cund 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 44344hier 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 47921in die Nachricht selbst einzufügen . Die letzte Ziffer des Stichtags 6gibt 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 0123456789in meinem Beispiel die Null-Indexierung verwendet . Sie können 1-Indizierung und 1234567890oder 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!

Sherlock9
quelle
1
adding the first two digits without addingMeinst du tragen?
Isaacg
@isaacg Ja, ich habe es getan. Bearbeitet
Sherlock9
Können Sie klarstellen, was Sie mit without borrowingund meinen without carrying? Meinst du addieren und subtrahieren mod 10, dh (6+7) mod 10 = 3und (6-8) mod 10 = 8?
R. Kap
@ R.Kap Ja, lass mich das klären.
Sherlock9
Haben wir haben abgrenzen Zahlen?
R. Kap

Antworten:

10

Python 3 , 1423 1348 1324 1316 1300 1286 1250 1249 1209 1206 1204 Bytes

Dies 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 und 0123456789beim Konvertieren gin t. Mein Schachbrett hat ein Format ähnlich dem folgenden Beispiel:

  2 9 7 4 5 8 3 1 0 6    # C
  S E N A T O R I        # keyword
0 B D G J L P U W Y .    # remaining alphabet arranged in columns
6 C F H K M Q V X Z #    # . and # at the end

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, tkompakter 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])zu sum(map(ord,s[i:i+2])). -2 Bytes vom Ändern von 2 +=[a]Aufrufen nach +=a,. -13 Bytes aus der Änderung, wie G()der Index des Minimums von gefunden s. -2 Bytes vom Ändern y=(y+1)%vzu y=-~y%v. -15 Bytes von der Zuweisung k.index()an K. -4 Bytes von der Zuweisung 10an W. -5 Bytes von der Zuweisung 1-I(d[-1])anX innen V. -3 Bytes von C()der Hauptschleife des Umschreibens . -2 Bytes von Reorganisation T().

I=int;L=list;E=len;R=range;B=str;J=''.join;W=10
def H(s,e):
 for i in R(e-E(s)):s+=chr(48+sum(map(ord,s[i:i+2]))%32%W)
 return s
def Q(s):
 r=[0]*E(s);s=L(s)
 for z in R(E(s)):b=s.index(min(s));r[b]=z;s[b]="~"
 return r
def T(x,k,d=0):
 u=E(x);v=E(k);g=R(v);K=k.index;n=u//v+1;w=[];e=r=y=0;i=K(y);c=[]
 if d:
  while r<n:
   if r>n-1:i=min(i,(u%v or v))
   w+=L(x[e:e+i]),;e+=i;i+=1;r+=1
   if i>v:y=-~y%v;i=K(y)
  r=y=0;i=v-K(y)
  while r<n:
   w[r]+=L(x[e:e+i]);e+=i;i-=1;r+=1
   if i<1:y+=1;i+=v-K(y);r+=1
  w[-1]+=['']*(v-E(w[-1]))
  for j in g:c+=J(z[j]for z in w),
 else:c=[x[i::v]for i in g]
 s=[0]*v
 for f in g:s[k[f]]=c[f]
 return J(s)
def C(m,s,w,n):
 t={".":s[-2:],"#":s[-1]*2};j=z=0
 for x in R(26):
  v=chr(x+65)
  if v in w:t[v]=s[w.index(v)]
  else:t[v]=s[z-2]+s[j];j+=z;z=-~z%2
 r=J(i.isdigit()and i or t[i]for i in m)
 return r+n[:-E(r)%5]
def V(m,w,P,d,A,M,n):X=1-I(d[-1]);t=J(B(Q(P[W:20])[I(J(B((I(H(J(B((I(M[i])-I(d[i]))%W)for i in R(5)),W)[i])+I(Q(P[:W])[i]))%W)for i in R(W))[i])])for i in R(W));u=H(t,60)[W:];p=A+I(u[-2]);v=T(u,Q(t));z=T(T(C(m,J(B(i)for i in Q(u[40:])),w,n),Q(v[:p])),Q(v[p:p+A+I(u[-1])]),1);e=[z[5*i:5*-~i]for i in R(-(-E(z)//5))];return' '.join(e[:X]+[M]+e[X:])

Ungolfing:

def chain_add(seq, end):
    for i in range(end - len(seq)):
        seq += chr(48+sum(map(ord,seq[i:i+2]))%32%10)
    return seq

def sequent(seq):
    res = [0]*len(seq)
    seq = list(seq)
    for z in range(len(seq)):
        b = seq.index(min(seq))
        res[b] = z
        seq[b] = "~"
    return res

def transpose(text, keys, disrupt=False):
    if disrupt:
        num_rows = len(text) // len(keys) + 1
        len_last = len(text) % len(keys)
        if len_last == 0:
            len_last = len(keys)
        d_rows = []
        text_index = 0
        current_row = 0
        stop_key = 0
        stop_index = keys.index(stop_key)
        while current_row < num_rows:
            if current_row > num_rows-1:
                stop_index = min(stop_index, len_last)
            d_rows += [list(text[text_index:text_index+stop_index])]
            text_index += stop_index
            stop_index += 1
            if stop_index>len(keys):
                stop_key = (stop_key+1) % len(keys)
                stop_index = keys.index(stop_key)
            current_row += 1
        current_row = 0
        stop_key = 0
        stop_len = len(keys) - keys.index(stop_key)
        while current_row < num_rows:
            d_rows[current_row] += list(text[text_index:text_index+stop_len])
            text_index += stop_len
            stop_len -= 1
            if stop_len < 1:
                stop_key += 1
                stop_len = len(keys) - keys.index(stop_key)
                current_row += 1
            current_row += 1
        d_rows[-1] += ['']*(len(keys)-len(d_rows[-1]))
        columns = []
        for j in range(len(keys)):
            columns += [''.join(i[j]for i in d_rows)]
    else:
        columns = ['']*len(keys)
        for t in range(len(text)):
            columns[t%len(keys)] += text[t]
    res = [0]*len(keys)
    for index in range(len(keys)):
        res[keys[index]] = columns[index]
    return''.join(res)

def checkerboard(message, seq, word, null):
    trans = {".":seq[-2:], "#":seq[-1]*2};res='';j=z=0
    for x in range(26):
        v = chr(x + 65)
        if v in word:
            trans[v] = seq[word.index(v)]
        else:
            trans[v] = seq[z-2] + seq[j]
            j += z
            z = (z+1) % 2
    for i in message:
        if i.isdigit():
            res += i
        else:
            res += trans[i]
    return res + null[:-len(res)%5]

def vic_cipher(message, keyword, phrase, date, agent, m_id, null):
    s1 = sequent(phrase[:10])
    s2 = sequent(phrase[10:20])
    a = ''.join(str((int(m_id[i])-int(date[i]))%10) for i in range(5))
    g = ''.join(str((int(a[i])+int(s1[i]))%10) for i in range(10))
    t = ''.join(str(s2[int(g[i])]) for i in range(10))
    u = chain_add(t,60)[10:]
    p = agent+int(u[-2])
    q = agent+int(u[-1])
    seqT = sequent(t)
    v = transpose(u,seqT)
    k1 = sequent(v[:p])
    k2 = sequent(v[p:p+q])
    c = ''.join(str(i)for i in sequent(u[40:]))
    x = checkerboard(message,c,keyword,null)
    y = transpose(x,k1)
    z = transpose(y,k2,1)
    e = [z[5*i:5*(i+1)] for i in range(-(-len(z)//5))]
    X = 1-int(date[-1])
    return ' '.join(e[:X] + [m_id] + e[X:])
Sherlock9
quelle
2
Python 3 erlaubt Unicode-Zeichen als Variablen, FYI.
Paul
Ändern, ord(seq[i])+ord(seq[i+1])um sum(map(ord,seq[i:i+2]))1 Charakter zu speichern, glaube ich.
3

C 2880 2769 2766 2762 2743 2741 2739 2699 2458 Bytes

#include<stdio.h>
#define m(x)malloc(x)
#define Y(x)strlen(x)
typedef int i;typedef char*c;c _(c A,i B,i D){if(D>=B){return A;}c C=m(Y(A)+2);sprintf(C,"%s%c",A,48+(A[D]+A[D+1]-96)%10);return _(C,B,D+1);}c l(c A){i J=Y(A);c P=m(J+2);for(i m=0;m<J;m++){P[m]=32;}for(i v=0;v<J;v++){char G;i R;for(i u=0;u<J;u++){R=u<1|A[u]<G?u:R;G=u<1|A[u]<G?A[u]:G;}P[R]=48+v;c V=m(J);for(i t=0;t<J;t++){V[t]=t!=R?A[t]:97;}A=V;}return P;}c S(c C,c N,c I,char U){srand(time(NULL));i M=Y(I);i O=Y(N);i R=rand()%M;c Q=m(M+1);for(i u=R;u<M;u++){Q[u-R]=I[u];}Q[M-R]=46;for(i H=0;H<R;H++){Q[H+M-R+1]=I[H];}c g=m(28);c V=m(28);strcat(V,C);sprintf(g,"%s%s",N,"BCDFGHJKLMPQUVWXYZ.#");i B=Y(N);for(i q=B;q<10;q++){for(i x=0;x<10;x++){char J[2]={C[q],C[x]};V[B]=48+atoi(J);B++;}}c w=m(M*2+4);for(i J=0;J<=M;J++){i K=0;for(i X=0;X<28;X++){if(Q[J]==g[X]){char F[3];sprintf(F,"%d",V[X]-48);strcat(w,F);K=1;}}if(K<1){w[Y(w)]=Q[J];}}i f=Y(w);if(f%5>0){c P=m(5-f%5);for(i E=0;E<5-f%5;E++){P[E]=U;}strcat(w,P);}return w;}c a(c I,c U){i M=Y(I),K=Y(U);c T=m(M);i F=0;for(i b=0;b<K;b++){for(i y=0;y<K;y++){if(U[y]==48+b){for(i u=y;u<M;u+=K){T[F]=I[u];F++;}}}}return T;}c da(c I,c K){i e=Y(I),k=Y(K);c T=m(e);for(i y=0;y<e;y++){T[y]=32;}i F,P;F=P=0;for(i u=0;u<k;u++){for(i v=0;v<k;v++){T[F]=I[P];P++;F++;if(K[v+1]-48==u){for(i C=1;C<k-v;C++){F+=k-v-C;for(i E=0;E<=v+C;E++){if(F<e&P<e){T[F]=I[P];}F++;P++;}}break;}}if(F>e){break;}}i U=0;for(i g=0;g<e;g++){U=T[g]-48<10&-1<T[g]-48?U+1:U;}for(i j=U;j<e;j++){for(i x=0;x<e;x++){if(T[x]==32){T[x]=I[j];break;}}}return a(T,K);}En(c n,c m,c k,i d,c v,c s,char u){c S1,S2;S1=m(10);S2=m(10);for(i i=0;i<20;i++){if(i<10){S1[i]=k[i];}else{S2[i-10]=k[i];}}S1=l(S1);S2=l(S2);c M=m(5);for(i i=4;i>-1;i--){M[i]=48+(s[i]-v[i])%10;}c G=_(M,5,0);for(i y=0;y<10;y++){G[y]=48+(S1[y]+G[y]-96)%10;}c N="0123456789";c T=m(10);for(i q=0;q<10;q++){for(i t=0;t<10;t++){if(N[t]==G[q]){T[q]=S2[t];}}}c Z=_(T,50,0);c U=m(50);for(i h=0;h<50;h++){U[h]=Z[h+10];}i p,q;for(i b=49;b>10;b++){if(U[b]!=U[b-1]){q=d+U[b]-48;p=d+U[b-1]-48;break;}}c V=m(50);i Ct=0;for(i j=0;j<10;j++){for(i o=0;o<10;o++){if(l(T)[o]==48+j){for(i x=o;x<o+41;x+=10){V[Ct]=U[x];Ct+=1;}}}}c K1=m(p);c K2=m(q);for(i D=0;D<p+q;D++){if(D<p){K1[D]=V[D];}else{K2[D-p]=V[D];}}K1=l(K1);K2=l(K2);c C=m(10);for(i b=40;b<50;b++){C[b-40]=U[b];}C=l(C);c t=da(a(S(C,m,n,u),K1),K2);i O=0;for(i B=0;B<Y(t)/5+1;B++){if(B==Y(t)/5-v[Y(v)-1]+49){printf("%s ",s);}else{for(i J=O;J<O+5;J++){printf("%c",t[J]);}printf(" ");O+=5;}}}

Meine 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.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

char*Chain_Add(char*String,int End,int Start){
  if(Start>=End){return String;}
  char*C=malloc(strlen(String)+2);
  sprintf(C,"%s%c",String,'0'+(((String[Start]-'0')+(String[Start+1]-'0'))%10));
  return Chain_Add(C,End,Start+1);
}

char*Sequent(char*String){
  int J=strlen(String);
  char*P=malloc(J+2);
  for(int m=0;m<J;m++){
    P[m]=' ';
  }
  for(int v=0;v<J;v++){
    char G;
    int R;
    for(int u=0;u<J;u++){
      R=(u<1||String[u]<G)?u:R;
      G=(u<1||String[u]<G)?String[u]:G;
    }
    P[R]='0'+v;
    char*V=malloc(J);
    for(int t=0;t<J;t++){
      if(t!=R){
    V[t]=String[t];
      }
      else{
    V[t]='a';
      }
    }
    String=V;
  }
  return P;
}

char*Straddling_Checkerboard(char*C,char*Key,char*Message,char null){
  srand(time(NULL));
  int Msg_Len=strlen(Message);
  int Key_Len=strlen(Key);
  int R=rand()%Msg_Len;
  char*Q=malloc(Msg_Len+1);
  for(int u=R;u<Msg_Len;u++){
    Q[u-R]=Message[u];
  }
  Q[Msg_Len-R]='.';
  for(int H=0;H<R;H++){
    Q[H+Msg_Len-R+1]=Message[H];
  }
  char*Alphabet=malloc(26);
  for(int W=0;W<26;W++){
    Alphabet[W]='A'+W;
  }
  int q=0;
  char*e=malloc(Key_Len);
  for(int z=0;z<Key_Len;z++){
    if(strchr(e,Key[z])!=NULL){
      q++;
    }
    else{
      e[z-q]=Key[z];
    }
  }
  int r=0;
  for(int h=0;h<26;h++){
    if(strchr(e,Alphabet[h-r])!=NULL){
      for(int X=h-r;X<26;X++){
    Alphabet[X]=Alphabet[X+1];
      }
      r++;
    }
  }
  char*Checkerboard=malloc(28);
  for(int i=0;i<26;i++){
    if(i<strlen(e)){
      Checkerboard[i]=e[i];
    }
    else{
      Checkerboard[i]=Alphabet[i-strlen(e)];
    }
  }
  Checkerboard[26]='.';
  Checkerboard[27]='#';
  char*Values=malloc(28);
  strcat(Values,C);
  int B=strlen(e);
  for(int q=B;q<10;q++){
    for(int x=0;x<10;x++){
      char J[2]={C[q],C[x]};
      Values[B]='0'+atoi(J);
      B++;
    }
  }
  char*Encoded=malloc(Msg_Len*2+4);
  for(int J=0;J<=Msg_Len;J++){
    int K=0;
    for(int X=0;X<28;X++){
      if(Q[J]==Checkerboard[X]){
    char F[3];
    sprintf(F,"%d",Values[X]-'0');
    strcat(Encoded,F);
    //printf("F = %s while Q[J] = %c and Checkerboard[X] = %c and Encoded = %s\n",F,Q[J],Checkerboard[X],Encoded);
    K=1;
      } 
    }
    if(K<1){
      Encoded[strlen(Encoded)]=Q[J];
    }
  }
  int Encded_Len=strlen(Encoded);
  if(Encded_Len%5>0){
    char*P=malloc(5-Encded_Len%5);
    for(int E=0;E<5-Encded_Len%5;E++){
      P[E]=null;
    }
  strcat(Encoded,P);
  }
  return Encoded;
}

char*Transpose(char*Message,char*K1){
  int Msg_Len=strlen(Message),K1_Len=strlen(K1);
  char*T=malloc(Msg_Len);
  int F=0;
  for(int i=0;i<K1_Len;i++){
    for(int y=0;y<K1_Len;y++){
      if(K1[y]=='0'+i){
    for(int u=y;u<Msg_Len;u+=K1_Len){
      T[F]=Message[u];
      F++;
    }
      }
    }
  }
  return T;
}

char*Disrupted_Transpose(char*Message,char*K2){
  int Msg_Len=strlen(Message),K2_Len=strlen(K2);
  char*T=malloc(Msg_Len);
  for(int y=0;y<Msg_Len;y++){
    T[y]=' ';
  }
  int F=0;
  int P=0;
  for(int u=0;u<K2_Len;u++){
    for(int v=0;v<K2_Len;v++){
      T[F]=Message[P];
      P++;F++;
      if(K2[v+1]-'0'==u){
        for(int C=1;C<K2_Len-v;C++){
      F+=K2_Len-v-C;
      for(int E=0;E<=v+C;E++){
        if(F<Msg_Len&P<Msg_Len){
          T[F]=Message[P];
        }
        F++;P++;
      }
    }
    break;
      }
    }
    if(F>Msg_Len){
      break;
    }
  }
  int U=0;
  for(int g=0;g<Msg_Len;g++){
    U=(T[g]-'0'<10&-1<T[g]-'0')?U+1:U;
  }
  for(int j=U;j<Msg_Len;j++){
    for(int x=0;x<Msg_Len;x++){
      if(T[x]==' '){
    T[x]=Message[j];
    break;
      }
    }
  }
  return Transpose(T,K2);
}

void VIC_Encoder(char*Message,char*Phrase,char*Key,int a_id,char*date,char*m_id,char null){
  char*S1=malloc(10);
  char*S2=malloc(10);
  for(int i=0;i<20;i++){
    if(i<10){
      S1[i]=Key[i];
    }
    else{
      S2[i-10]=Key[i];
    }
  }
  S1=Sequent(S1);
  S2=Sequent(S2);
  char*M=malloc(5);
  for(int i=4;i>-1;i--){
    M[i]='0'+(((m_id[i]-'0')-(date[i]-'0'))%10);
  }
  char*G=Chain_Add(M,5,0);
  for(int y=0;y<10;y++){
    G[y]='0'+(((S1[y]-'0')+(G[y]-'0'))%10);
  }
  char*N="0123456789";
  char*T=malloc(10);
  for(int q=0;q<10;q++){
    for(int t=0;t<10;t++){
      if(N[t]==G[q]){
    T[q]=S2[t];
      }
    }
  }
  char*Z=Chain_Add(T,50,0);
  char*U=malloc(50);
  for(int h=0;h<50;h++){
    U[h]=Z[h+10];
  }
  int p,q;
  for(int b=49;b>10;b++){
    if(U[b]!=U[b-1]){
      q=a_id+(U[b]-'0');
      p=a_id+(U[b-1]-'0');
      break;
    }
  }
  char*seqT=Sequent(T);
  char*V=malloc(50);
  int Count=0;
  for(int j=0;j<10;j++){
    for(int o=0;o<10;o++){
      if(seqT[o]=='0'+j){
    for(int x=o;x<o+41;x+=10){
      V[Count]=U[x];
      Count+=1;
    }
      }
    }
  }
  char*K1=malloc(p);
  char*K2=malloc(q);
  for(int D=0;D<p+q;D++){
    if(D<p){
      K1[D]=V[D];
    }
    else{
      K2[D-p]=V[D];
    }
  }
  K1=Sequent(K1);
  K2=Sequent(K2);
  char*C=malloc(10);
  for(int b=40;b<50;b++){
    C[b-40]=U[b];
  }
  C=Sequent(C);
  char*Transposed_2=Disrupted_Transpose(Transpose(Straddling_Checkerboard(C,Phrase,Message,null),K1),K2);
  int O=0;
  for(int B=0;B<strlen(Transposed_2)/5+1;B++){
    if(B==strlen(Transposed_2)/5-date[strlen(date)-1]+'1'){
      printf("%s ",m_id);
    }
    else{
      for(int J=O;J<O+5;J++){
    printf("%c",Transposed_2[J]);
      }
      printf(" ");
      O+=5;
    }
  }
}

Anmerkungen

  • Hierbei wird ein Schachbrett verwendet, das der folgenden Abbildung ähnelt, um die Nachricht zu codieren:

      3 4 5 6 2 3 4 5 6 7
      S E N A T O R I     
    6 B C D F G H J K L M 
    7 P Q U V W X Y Z . #
    
  • 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.

R. Kap
quelle
2

JavaScript (ES6), 946 938 953 Bytes

V=(c,d,f,g,j,k,m)=>{S=a=>a.split``,J=a=>a.join``,A=(a,b)=>{for(i=0;a[L="length"]<b;a+=(a[i++]- -a[i])%h);return a},Q=b=>(a=S(b).sort(),S(b).map(b=>a[i=a[X="indexOf"](b)]=i)),u=A(t=J(S(A(J(S(k).map((a,b)=>Math.abs(a-g[b]))),h=10)).map((a,b)=>Q(f[C="slice"](h,20))[(Q(f[C](0,h))[b]- -a)%h])),60)[C](h),T=((a,b,c)=>{if(r=Array(l=b[L]).fill(""),c){for(e=a[L]/l,i=0,w=[],u=R=b[X](x=0);i<e;)w[i++]=a[P](0,R++),u?u=0:R>l||(R=b[X](u=++x));for(i=0;i<e;)w[i]=J(w[i].concat(a[P](0,l-w[i++][L])));a=J(w)}for(i in a)r[+b[i%l]]+=a[i];return r}),v=J(T(u,Q(t))),q=J(Q(u[C](-h))),t="ABCDEFGHIJKLMNOPQRSTUVWXYZ#".match(new RegExp("[^"+d+"]","g")),t[P="splice"](9,0,"."),M=[];for(i in t)M[t[i]]=q[8^i/h]+(M[d[i]]=q[i%h]);for(n=c[L],b=J((c[C](n-=new Date%n)+"."+c[C](0,n)).split(/ |/).map(a=>M[a]||a)),b+=m.repeat(5-b[L]%5),i=f=q=49;f==q;)f=+u[i-1]+j,q=+u[i++]+j;return t=J(T(S(J(T(b,Q(v[C](0,f))))),Q(v.substr(f,q)),1)).match(/.{5}/g),g=-g[C](-1),g++&&t[P](g||t[L],0,k),t}

Ich 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

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

chainAdd = (s,l)=>{for(i=0;s.length<l;s+=(s[i++]- -s[i])%10);return s;}

sequentialize = (s)=> {
    a=s.split('').sort();
    return s.split('').map(c=>(i=a.indexOf(c),a[i]='',i));  
}

transpose = (s,k,disruptive)=>{
    var result=Array(k.length).fill('')
    if(disruptive){
        rows=[]
        k_index=0;
        rowLength=k.indexOf(k_index);
        triangling=!rowLength;

        expectedRows = s.length/k.length
        for(row=0;row<expectedRows;row++){
            rows[row]=s.splice(0,rowLength++)
            if(triangling){     
                if(rowLength>k.length){
                    triangling=false;
                    rowLength=k.indexOf(++k_index)              
                }
            }
            else{               
                triangling=true;
            }
        }

        for(row=0;row<expectedRows;row++){
            rows[row]= rows[row].concat(s.splice(0,k.length-rows[row].length)).join('')
        }
        s=rows.join('')
    }
    for(i in s)
        result[+k[i%k.length]]+=s[i];   
    return result;
}

checkerboard =(message,seq, keyword, nulls)=>{  
    t='ABCDEFGHIJKLMNOPQRSTUVWXYZ#'.match(new RegExp('[^'+keyword+']','g'));
    t.splice(9,0,'.')

    map=[]
    for(i in t)
        map[t[i]]=(seq[8^(i/10)])+(map[keyword[i]]=seq[i%10])

    r = new Date%message.length;
    rotateMessage=message.substr(message.length-r)+'.'+message.substr(0,message.length-r)

    result =rotateMessage.split(/ |/).map(x=>map[x]||x).join('');
    result+=nulls.repeat(5-result.length%5)

    return result;
}

vic = (message, keyword, phrase, date, agent, m_id, nulls)=>{
    s1=sequentialize(phrase.substr(0,10))//.join('')
    s2=sequentialize(phrase.substr(10,10))//.join('')

    r = m_id.split('').map((x,i)=>Math.abs(x-date[i])).join('')
    g = chainAdd(r,10).split('').map((x,i)=>(s1[i]- -x)%10);

    t = g.map(i=>s2[+i]).join('');
    u=chainAdd(t,60).substr(10)

    var p,q;
    for(i=49;p==q;i++){
        p=agent + +u[i-1];
        q=agent + +u[i];
    }
    seqT = sequentialize(t);
    v=transpose(u,seqT).join('');

    k1 = sequentialize(v.substr(0,p));
    k2 = sequentialize(v.substr(p,q));
    c  = sequentialize(u.substr(-10)).join('')

    CB =checkerboard(message,c, keyword, nulls);
    t1=transpose(CB,k1).join('')
    t2=transpose(t1.split(''),k2,1).join('').match(/.{5}/g);
    (d=-date.substr(-1))&&t2.splice((d+1)||t2.length,0,m_id);
    return t2;
}

Anmerkungen

  • Hierbei wird ein Schachbrett verwendet, das der folgenden Abbildung ähnelt, um die Nachricht zu codieren:

      3 1 0 5 9 6 8 7 2 4
      S E N A T O R I
    2 B C D F G H J K L .
    4 M P Q U V W X Y Z #
    
  • 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.

SLuck49
quelle
Könnten Sie bitte ein Snippet hinzufügen, damit ich überprüfen kann, ob dies funktioniert? Wenn ja, kann ich Ihnen das Kopfgeld gewähren.
R. Kap
@ R.Kap Sicher, ich habe ein Demo-Snippet hinzugefügt
SLuck49
Hmm ... in der Demo message identifierscheint das 7vom Ende weg zu sein 6. Auch in Ihrer ungolfed Version Idscheint das gleiche 6vom Anfang weg zu sein, anstatt vom Ende.
R. Kap
@ R.Kap Ja, es gab einen Fehler, als ich ihn zum ersten Mal gepostet habe (muss ihn nicht in der Ungolfed behoben haben). Was den Golf betrifft, so habe ich angenommen, dass er 0-indiziert ist, denn ansonsten, wenn das 1heißt, am Ende, wo würdest du sagen, message identifiersollte das weitergehen 0? Ich kann es ändern, ich muss es nur wissen.
SLuck49
Ich würde sagen , dass auf eine 0der message identifiersollte von der Ausgabe weggelassen werden.
R. Kap
1

Clojure, 1197 - 1212 Bytes

Oh, 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.

(defn enc[I K E D Y M](let[P split-at A concat Z zipmap R partition W mapcat % count X repeat O vector / map x(fn[C](apply / O C))G range t 10 r(G t)m(fn[i](mod i t))F(fn[[n & N]](/ last(iterate(fn[[[b & N]a]][(A N[(m(+ a b))])b])[N n])))Q(fn[S](for[i(G(% S))a[(nth S i)]](apply +(%(filter #{a}(take i S)))(for[b S :when(pos?(compare a b))]1))))[S J](/ Q(P t(take 20 E)))T(/(Z r J)(/ m(/ + S(F(/ - M D)))))U(take 50(drop t(F T)))l(last U)p(+ Y(last(remove #{l}U)))V(W(Z(Q T)(x(R t U)))r)[k j](/ Q(P p(take(+ p Y l)V)))B(into(Z(/ char(G 48 58))(G))(/(fn[i c][c(+(*(quot i 10)20)(nth(Q(reverse(take t(reverse U))))(m i)))])(G)(A(str K",,")(remove(set K)(/ char(A(G 65 91)".#"))))))?(% k)T(vec(filter some?(W(Z k(x(R ?(A(flatten(R 5(A(W str(/ B(let[[b e](P(rand-int(count I))I)](apply str(A e".. "b)))))(X 4(B\,)))))(X(dec ?)nil)))))(G ?))))w (% j)NR(+(quot(% T)w)1)L(flatten(for[k r](for[i(G(.indexOf j k)(inc w))](G i))))C(for[[r c](/ O(rest(reductions + -1(/(fn[i](get{0 1}i 0))L)))L):when(< r NR)][r c])H(R 5(filter some?(W(Z j(x(R w (A(vals(into(sorted-map)(/ O(A C(for[i(G NR)j(G w)c[[i j]]:when(not((set C)c))]c))T)))(X(dec w)nil)))))(G w))))](/(fn[p](apply str p))(let[[b e](P(-(% H)(D 6)-1)H)](A b[M]e)))))

Beispieleingaben und Testfall:

(def mymsg (clojure.string/upper-case "We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot#3#"))
(def mykey "SENATORI")
(def mypharase (clojure.string/upper-case (apply str (remove #{\space} "The first principle is that you must not fool yourself — and you are the easiest person to fool."))))
(def mydate [3 1 7 2 0 1 6])
(def mynum 9)
(def M [4 7 9 2 1])

;("61231" "12824" "71192" "58609" "92185" "48612" "14927" "22944" "34046" "13348" "04159" "38645" "70546" "20254" "22026" "64584" "21904" "47921" "90253" "42694" "42221" "56644" "14541")
(enc mymsg mykey mypharase mydate mynum M)

Ungolfed:

(defn enc[mymsg mykey mypharase mydate mynum M]
  (let[t       10
       r       (range t)
       m       (fn[i](mod i t))
       lagfib  (fn[[n & N]](map last(iterate(fn[[[b & N]a]][(concat N[(m(+ a b))])b])[N n])))
       toseq   (fn[S](for[i(range(count S))a[(nth S i)]](apply +(count(filter #{a}(take i S)))(for[b S :when(pos?(compare a b))]1))))
       [S1 S2] (map toseq(split-at t(take 20 mypharase)))
       M2      (take t(lagfib(map - M mydate)))
       G       (map m(map + S1 M2))
       Gmap    (zipmap r S2)
       T       (map Gmap G)
       U       (take 50(drop t(lagfib T)))
       L2      (last U)
       L1      (last(remove #{L2}U))
       p       (+ mynum L1)
       q       (+ mynum L2)
       seqT    (toseq T)
       V       (mapcat(zipmap seqT(apply map vector(partition t U)))r)
       [K1 K2] (map toseq(split-at p(take(+ p q)V)))
       C       (toseq(reverse(take t(reverse U))))
       B       (into(zipmap(map char(range 48 58))(range))(map(fn[i c][c(+(*(quot i 10)20)(nth C(m i)))])(range)(concat(str mykey",,")(remove(set mykey)(map char(concat(range 65 91)".#"))))))
      ;B       (into(zipmap(map char(range 48 58))(range))(map(fn[i c][c(+(nth C(quot i 3))(*(mod i 3)20))])(range)(flatten(apply map vector(partition 10(apply concat mykey",,"(apply map vector (partition 2(remove(set mykey)(map char(concat(range 65 91)".#")))))))))))
       N1      (count K1)
       mymsg   (flatten(partition 5(concat(mapcat str(map B(let[[b e](split-at 49 mymsg)](apply str(concat e".. "b)))))(repeat 4(B\,)))))
       T1      (vec(filter some?(mapcat(zipmap K1(apply map vector(partition N1(concat mymsg(repeat(dec N1)nil)))))(range N1))))
       N2      (count K2)
       NR      (+(quot(count T1)N2)1)
       cols    (flatten(for[k r](for[i(range(.indexOf K2 k)(+(count K2)1))](range i))))
       rows    (rest(reductions + -1(map(fn[i](get{0 1}i 0))cols)))
       coords  (for[[r c](map vector rows cols):when(< r NR)][r c])
       coords  (concat coords(for[i(range NR)j(range N2)c[[i j]]:when(not((set coords)c))]c))
       T2      (partition 5(filter some?(mapcat(zipmap K2(apply map vector(partition N2(concat(vals(into(sorted-map)(map vector coords T1)))(repeat(dec N2)nil)))))(range N2))))]
    (map(fn[p](apply str p))(let[[b e](split-at(-(count T2)(mydate 6)-1)T2)](concat b[M]e)))))

Es gibt eine alternative Implementierung auf dem Schachbrett, Bdie 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.

NikoNyrh
quelle
Erwog, eine Clojure-Lösung zu schreiben, aber mein Kopf explodierte, als ich die Frage las. Wie lange hat das geschrieben?
Carcigenicate
Vielleicht 3 Stunden, während Sie nebenbei Youtube schauen. Das fing ganz einfach an, aber ich wollte aufgeben, als ich die zweite "gestörte Umsetzung" durchführen musste. Dies coordswird 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.
NikoNyrh
Oh verdammt, ich habe vergessen, den hartcodierten Split-Punkt bei zu ändern (split-at 49 mymsg), 49 sollte so etwas wie eine (rand-int(count mymsg))richtige Antwort sein, die etwas über 1200 Bytes liegt. zzz
NikoNyrh
Verdammt. Wahrscheinlich immer noch weniger als die Antwort.
Carcigenicate