VIC szyfr jest jednym z najbardziej skomplikowanych ołówek i papier szyfrów kiedykolwiek wymyślono. Używany w latach 50. XX wieku przez radzieckiego szpiega Reino Häyhäna, o kryptonimie „ZWYCIĘZCA”, jego główną zasadą jest bezpieczeństwo poprzez zaciemnianie; dużo od zaciemniania.
Twoim zadaniem jest napisanie programu lub funkcji, która odbierze komunikat i zakoduje go za pomocą szyfru VIC. Mam również opublikował tutaj VIC szyfr dekodera wyzwanie . Jeśli którakolwiek z poniższych instrukcji jest niejasna, nie wahaj się zapytać o nią w komentarzach. Instrukcje są dostosowane z tej strony .
Kodowanie szyfru VIC
Przygotowanie
Będziesz potrzebował pięciu danych wejściowych:
- wiadomość w postaci zwykłego tekstu
- krótkie słowo kluczowe lub wyrażenie zawierające najczęściej używane litery w Twoim języku
- fraza kluczowa, taka jak cytat lub wiersz utworu (co najmniej 20 znaków)
- data (lub inny numer składający się z sześciu cyfr lub więcej)
- osobisty numer agenta
W praktyce te cztery ostatnie powinny zostać wcześniej uzgodnione przez nadawcę i odbiorcę, w tym to, czy do kodowania używany jest numer agenta nadawcy lub odbiorcy.
Moja przykładowa wiadomość będzie: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.
Będziemy kodować w języku angielskim (chociaż możesz używać dowolnego języka i alfabetu, który preferujesz), a najczęściej używane litery w alfabecie angielskim A, E, I, N, O, R, S, T
. Użyję słowa kluczowegoSENATORI
.
Moją kluczową frazą jest cytat Richarda Feynmana: „Pierwszą zasadą jest to, że nie możesz oszukiwać siebie - i jesteś najłatwiejszą osobą do oszukania”.
Jako datę użyję 31 lipca 2016 r. (W formacie 3172016
), czyli w dniu, w którym napisałem ten opis.
Numer osobisty, który wybrałem dla siebie to 9
.
Podsumowanie kroków
- Uzyskaj klucze pośrednie do użycia w poniższych krokach.
- Zbuduj i zastosuj rozstawioną szachownicę.
- Zbuduj i zastosuj pierwszą tabelę transpozycji.
- Skonstruuj i zastosuj drugą (zakłóconą) tabelę transpozycji.
- Sfinalizuj wiadomość, wstawiając grupę wskaźników wiadomości.
Submechanizmy
Jeszcze dwie rzeczy do wyjaśnienia, zanim przejdziemy do sedna sprawy: procesy dodawania łańcucha i sekwencjonowania.
Dodawanie łańcucha, znane również jako opóźniony generator Fibonacciego, polega na pobraniu początkowej sekwencji cyfr, dodaniu pierwszych dwóch cyfr bez przenoszenia (następnie ich dodaniu mod 10
) i dołączeniu wyniku na końcu. Na przykład:
79081
7 + 9 = 6
790816
9 + 0 = 9
7908169
0 + 8 = 8
79081698
8 + 1 = 9
790816989
1 + 6 = 7
7908169897
... and so on
Sekwencjonowanie polega zasadniczo na ciągnięciu sekwencji liter lub cyfr i oznaczaniu ich według kolejności alfabetycznej / numerycznej. Duplikaty są oznaczone od lewej do prawej. Na przykład:
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
Używam tutaj indeksowania zerowego, ale indeksuj, jak chcesz.
1. Klucze pośrednie
Podziel pierwsze 20 liter frazy kluczowej na dwie grupy po 10 i zsekwencjonuj każdą z osobna, którą nazwiemy S1
i S2
.
THEFIRSTPR
S1: 8201357946
INCIPLEIST
S2: 2603751489
Wybierz losowy 5-cyfrowy identyfikator wiadomości M
(może to być jedno z danych wejściowych, jeśli wolisz):
M = 47921
Odejmij, bez pożyczania (odejmij mod 10
), pierwsze pięć cyfr kluczowej daty 3172016
od M
:
M 47921
date - 31720
= 16201
Dodaj łańcuch, aż uzyskasz dziesięć cyfr:
1620178218
Dodaj te cyfry S1
, bez przenoszenia lub mod 10
, aby uzyskać G
:
1620178218
S1 + 8201357946
G = 9821425154
Powyżej S2
wpisz sekwencję 0123456789. Znajdź każdą cyfrę G
w sekwencji 0123456789 i zastąp ją cyfrą bezpośrednio poniżej S2
. Rezultatem jest T
.
0123456789
S2 2603751489
G 9821425154
T 9806705657
Użyj dodawania łańcucha, aby rozwinąć T
do 60 cyfr.
9806705657
becomes
980670565778637511245490262369939288595822106344304316978734
Te ostatnie 50 cyfr, w pięciu rzędach po dziesięć cyfr, tworzą U
blok.
T 9806705657
U 7863751124
5490262369
9392885958
2210634430
4316978734
Ostatnie dwie nierówne cyfry U
bloku są indywidualnie dodawane do numeru osobistego agenta, aby podać szerokość dwóch transpozycji, p
oraz q
.
9 + 3 = 12 (p, pierwsza szerokość transpozycji) 9 + 4 = 13 (q, druga szerokość transpozycji)
Sequentialize T
i używać tej sekwencji skopiować off kolumny z U
bloku, od góry do dołu, do nowego rzędu cyfr V
.
T 9806705657
seqT 9804612537
U 7863751124
5490262369
9392885958
2210634430
4316978734
V 69911 56837 12548 26533 30206 13947 72869 49804 84323 75924
Sekwencjonuj pierwsze p
cyfry, aby uzyskać klucz dla pierwszej transpozycji K1
, oraz kolejne q
cyfry dla klucza dla drugiej 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
Na koniec zsekwencjonuj ostatni wiersz U
bloku, aby uzyskać C
, nagłówki kolumn dla szachownic okiennych:
U5 4316978734
C 3105968724
2. Straddling Checkerboard
Najpierw dam przykładową szachownicę, a następnie wyjaśnię zasady jej tworzenia w następujący sposób:
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 #
Pierwszy wiersz liter to nasze krótkie słowo kluczowe SENATORI
. Twoim słowem kluczowym może być dowolny ciąg bez duplikatów, ale ponieważ określa górny rząd twojej szachownicy, wybierz mądrze. Powyżej słowa kluczowego jest C
, a pozostałe wiersze to reszta alfabetu w dowolnej kolejności. W moim przypadku wypełniłem szachownicę resztą alfabetu łacińskiego, znakiem interpunkcyjnym .
i znakiem dla oznaczania liczb #
. Zasadniczo szachownica jest fantazyjnym szyfrem zastępczym. Na przykład „E” zostanie zastąpione przez 1
, a „W” zostanie zastąpione przez 27
.
Po zakodowaniu naszej wiadomości w postaci zwykłego tekstu za pomocą tej szachownicy, najpierw musimy uczynić początek naszej wiadomości mniej oczywistym, dzieląc ją w losowej pozycji i nadając jej wielkie litery. Aby oznaczyć drugi oryginalny początek, używamy dwóch kropek..
We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.
staje się
HING ELSE. MOVE TO SAFEHOUSE FOXTROT#3#.. WE ARE
DISCOVERED. TAKE WHAT YOU CAN. BURN EVERYT
Kodujemy za pomocą szachownicy, co daje nam:
407020 1293124 496481 96 354114062831 416479869443442424 271 581
2173436481812124 95451 274059 22628 435024 232880 14818229
Jeśli długość wiadomości nie jest podzielna przez 5, dodajemy puste znaki, aby wypisać wiadomość. Nasza wiadomość ma 109 cyfr, więc dodam jeden null: „4”.
40702 01293 12449 64819 63541 14062 83141 64798 69443 44242 42715
81217 34364 81812 12495 45127 40592 26284 35024 23288 01481 82294
Uwaga: Ponieważ moja przykładowa wiadomość nie zawiera liczb, powiem tutaj, że możesz wyznaczyć, powiedzmy, as #3#
, który jest zakodowany jak 44344
tutaj.
3. Pierwsza transpozycja
Utwórz tabelę transpozycji, pisząc K1
(z sekcji Klawisze pośrednie), a następnie zakodowaną wiadomość z poprzedniego kroku, w wierszach o tej samej długości, poniżej klucza:
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
Biorąc ponumerowane kolumny w kolejności ich liczb, otrzymujemy:
060826428 246674580 151411542 246272922 961311401 082918141
4414434239 118451234 334422028 293488758 0417249224 794943568
4. Druga transpozycja
Pierwsza transpozycja była stosunkowo prosta. Ta jednak jest zakłóconą transpozycją. Wzorzec zakłóceń zależy od szerokości stołu i klucza. W naszym przykładzie mamy 110 cyfr i 13 kolumn, co oznacza, że będziemy mieli 8 pełnych wierszy i 6 resztek. Zaczynamy wypełniać pierwszy wiersz, ale zatrzymujemy się w kolumnie 0 i kontynuujemy w następujący sposób:
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
Następnie wypełniamy kilka ostatnich miejsc pozostałymi cyframi.
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
Teraz odczytujemy kolumny dokładnie w taki sam sposób, jak w pierwszej transpozycji.
71431148 42711925 861904185 22614147 45499243 28261334 80218938
641701404 025244820 645224398 271283226 94944438 064214521
I podziel wszystko na 5-cyfrowe grupy:
71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189
38641 70140 40252 44820 64522 43982 71283 22694 94443 80642 14521
5. Sfinalizuj wiadomość
Ostatnim krokiem jest wstawienie naszego losowego identyfikatora 47921
wiadomości do samej wiadomości. Ostatnia cyfra kluczowej daty 6
wskazuje odległość, jaką powinna przebyć grupa od końca.
71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189 38641
70140 40252 44820 64522 43982 47921 71283 22694 94443 80642 14521
Uwagi do tego wyzwania
- Otrzymujesz co najmniej pięć danych wejściowych: wiadomość, słowo kluczowe z literą, frazę kluczową, datę i numer osobisty. Możesz dołączyć dwa dodatkowe dane wejściowe: identyfikator losowej wiadomości i wartości zerowe potrzebne do uzupełnienia wiadomości, lub twoja funkcja może wygenerować kilka liczb losowych samodzielnie.
- Możesz założyć, że wszystkie dane wejściowe są prawidłowe, z poprawną liczbą cyfr i liter (5-cyfrowy identyfikator wiadomości, co najmniej 20 cyfr dla frazy kluczowej i tak dalej). Możesz założyć, że w twoich ciągach (komunikat i słowa kluczowe) zostały już usunięte wszystkie znaki interpunkcyjne i spacje, z wyjątkiem tych, na które zezwalasz w swojej wersji, a liczby są już oznaczone znakami liczbowymi.
- Pierwsze słowo kluczowe nie powinno zawierać zduplikowanych liter, a w kodzie możesz założyć, że nigdy nie ma zduplikowanych liter.
- Język, w którym kodujesz, nie ma znaczenia, o ile istnieje on wcześniej, alfabet już istnieje i określasz, którego języka użyjesz w odpowiedzi.
- Niezależnie od tego, który alfabet zastosujesz do swojej szachownicy, możesz dodawać lub usuwać symbole, aby wypchnąć szachownicę. Określ, do czego używasz tych symboli (na przykład interpunkcja, osobny symbol „początek wiadomości”, symbole popularnych słów). Możesz całkowicie zrezygnować ze znaku liczbowego i przeliterować cyfry lub dołączyć każdą cyfrę do szachownicy, używając szczeliny, w której znak liczbowy oznaczał coś innego. Proszę podać, której szachownicy użyłeś w swojej odpowiedzi.
- Dane wyjściowe powinny być ciągiem oddzielonych spacjami pięciocyfrowych grup, listą pięciocyfrowych liczb całkowitych lub czymś podobnym.
- Użyłem indeksowania zerowego i
0123456789
w moim przykładzie. Możesz użyć 1-indeksowania i1234567890
/ lub innego systemu w swojej odpowiedzi, pod warunkiem, że określisz, czego użyłeś.
Oto przykładowa implementacja Ideone .
To jest długi post i napisałem go większość ręcznie, więc jeśli w tym poście są jakieś mylące części lub błędy w liczeniu i transpozycji, daj mi znać. Powodzenia i dobrej gry w golfa!
źródło
adding the first two digits without adding
Masz na myśli noszenie?without borrowing
iwithout carrying
? Masz na myśli dodawanie i odejmowanie mod10
, tj.(6+7) mod 10 = 3
I(6-8) mod 10 = 8
?Odpowiedzi:
Python 3 ,
14231348132413161300128612501249120912061204 bajtówTo zdecydowanie najdłuższy golf, jaki kiedykolwiek uprawiałem, i jedyny golf, w którym bardzo martwiłem się brakiem nazw zmiennych jednoznakowych. Sugestie dotyczące gry w golfa mile widziane. Wypróbuj online!
Koduję przy użyciu wielkich liter alfabetu łacińskiego z dodatkowymi znakami
.
oraz#
przy użyciu indeksowania 0 i0123456789
podczas konwersjig
nat
. Mój szachownica ma format podobny do następującego przykładu:Edycja: -63 bajty dzięki sugestii TuukkaX, aby skrócić niektóre często używane funkcje za pomocą zmiennych jednoliterowych. -12 bajtów od uczynienia
a, g, t
bardziej kompaktowym.Edytować: -24 bajtów od utworzenia poprzez usunięcie nazw zmiennych dla kluczy pośrednich, które są używane tylko raz, a mianowicie
a, g, s, S, k, K
.Edytować: -74 bajty z konsolidacji
H(), T() and C()
.Edycja: -1 bajtów dzięki Nickowi A za sugestię zmiany
ord(s[i])+ord(s[i+1])
nasum(map(ord,s[i:i+2]))
. -2 bajty ze zmiany 2+=[a]
wywołań na+=a,
. -13 bajtów od zmiany sposobuG()
znalezienia indeksu minimums
. -2 bajty od zmianyy=(y+1)%v
nay=-~y%v
. -15 bajtów od przypisaniak.index()
doK
. -4 bajty od przypisania10
doW
. -5 bajtów od przypisania1-I(d[-1])
doX
wewnątrzV
. -3 bajty zC()
głównej pętli przepisywania . -2 bajty z reorganizacjiT()
.Ungolfing:
źródło
ord(seq[i])+ord(seq[i+1])
nasum(map(ord,seq[i:i+2]))
zapisywanie 1 postaci, którą wierzę.C,
288027692766276227432741273926992458 bajtówMój Boże. To najdłuższy program, jaki kiedykolwiek miałem miałem do gry w golfa. Jest to również pierwszy przypadek, w którym skończyły mi się nazwy zmiennych jednoznakowych dla zakresu globalnego i dlatego musiałem przejść do korzystania z kilku 2-znakowych zmiennych (fakt, że najwyraźniej nie mogę ponownie zmienić zmiennych, nie pomaga). Wskazówki dotyczące gry w golfa są zatem bardzo mile widziane.
Bez golfa
Kompiluje bez ostrzeżeń, w przeciwieństwie do wersji golfowej. Niewielkie zmiany wprowadzone w wersji golfowej nie zostaną odzwierciedlone w tej wersji bez golfa.
Notatki
Używa szachownicy podobnej do poniższej, aby zakodować wiadomość:
Zakłada się, że wszystkie odpowiednie ciągi znaków są podane wielkimi literami. Wiadomość powinna również zawierać wszystkie znaki interpunkcyjne z wyjątkiem kropek i wszystkie cyfry wyznaczone przez
#
s, a fraza kluczowa powinna mieć usunięte wszystkie znaki interpunkcyjne.Wynikowy zakodowany komunikat jest wyprowadzany do STDOUT jako ciąg oddzielonych spacjami pięciocyfrowych grup.
Komunikat wejściowy powinien być w języku angielskim.
Połączyłbym kilka funkcji, których użyłem, ale musiałbym użyć więcej dwuliterowych nazw zmiennych, dzięki czemu końcowy program byłby dłuższy niż przy kilku dodatkowych funkcjach.
Obecnie nie zakłada się, że słowo kluczowe (przynajmniej w języku angielskim) zawsze będzie zawierało ten sam zestaw liter, a więc rekompensuje to poprzez usunięcie duplikatów, manipulowanie szachownicą itp. OP nie ma takiej możliwości, więc obecnie gram w zbędne dodatkowe niepotrzebne bajty.Zaktualizowano dla wersji golfowej.źródło
JavaScript (ES6),
946938953 bajtówW weekend widziałem, że nie było jeszcze wpisu do JS, więc oto moja (ostatnia minuta) próba. Wdrożenie i gra w golfa były szalone i zabawne!
Fragment demonstracyjny
Pokaż fragment kodu
Edycja: -8 bajtów
Uświadomiono sobie, że istnieją dodatkowe nawiasy wokół funkcji
S,J,A,Q
Edycja: +15 bajtów
Zaktualizowano logikę dotyczącą sposobu
message id
umieszczania znaku w końcowym komunikacie (teraz indeksowany 1, a 0 nie uwzględnia go w danych wyjściowych).Bez golfa
Notatki
Używa szachownicy podobnej do poniższej, aby zakodować wiadomość:
Wszystkie ciągi znaków są podane wielkimi literami. Wiadomość jest alfanumeryczna łacińska (plus
.
i#
) i powinna zostać usunięta cała interpunkcja (z wyjątkiem kropek). Wszystkie liczby powinny już być oznaczone#
s. Fraza kluczowa powinna zawierać wszystkie znaki interpunkcyjne / spacje.Wynikowy komunikat jest zwracany jako tablica 5-cyfrowych ciągów znaków.
Ulepszenia
Wydaje mi się, że istnieje sposób na nadużycie „Wszystkich języków” w celu zaoszczędzenia niektórych bajtów. Gdybym miał więcej czasu, skonfigurowałbym to tak, aby zakładać, że język jest podobny do hawajskiego, który ma tylko 12 liter.
Wszelkie sugestie dotyczące gry w golfa są zawsze mile widziane.
źródło
message identifier
wydaje się być7
daleko od końca6
. Również w twojej wersji bez golfa to samoId
wydaje się być6
od początku zamiast od końca.1
oznacza to sam koniec, gdzie powiedziałbyś, żemessage identifier
powinieneś iść na0
? Mogę to zmienić, muszę tylko wiedzieć.0
message identifier
Clojure,
11971212 bajtówOch, jestem wykończony.
Aktualizacja: Dodano wymaganą losową lokalizację podziału wiadomości, wersja bez golfa używa tej samej lokalizacji jak w podanym przykładzie, dzięki czemu algorytm można łatwo zweryfikować.
Przykładowe dane wejściowe i przypadek testowy:
Nie golfowany:
Ma alternatywną implementację na szachownicy,
B
która jest taka sama jak w definicji zadania. Ale zgłoszenie wykorzystuje inny, w którym nieużywane alfabety najpierw wypełniają drugi wiersz, a następnie trzeci zamiast wypełnienia kolumna po kolumnie.źródło
coords
jest generowany dwukrotnie, najpierw generując kształt trójkąta, a następnie wypełniając brakujące współrzędne. Również „wypełnienie do długości wielokrotności N” może mieć bardziej eleganckie rozwiązanie niż połączenie elementów N-1 i podział na długości N.(split-at 49 mymsg)
49, powinno to być coś w rodzaju,(rand-int(count mymsg))
więc poprawna odpowiedź to nieco ponad 1200 bajtów. zzz