Serwis Edukacyjny w I-LO w Tarnowie Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej Autor artykułu: mgr Jerzy Wałaszek |
©2024 mgr Jerzy Wałaszek |
ProblemNależy opracować uproszczony algorytm szyfrowania przy pomocy niemieckiej maszyny Enigma. |
Szyfry podstawieniowe (ang. substitution ciphers) polegają na zastępowaniu liter tekstu jawnego innymi literami (lub znakami) wg określonej reguły. Poznany przez nas wcześniej Szyfr Cezara jest takim właśnie szyfrem podstawieniowym. Prosty szyfr podstawieniowy możemy skonstruować w sposób następujący:
Przykład:
Zapisujemy dwa wiersze liter
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
Dolny wiersz mieszamy losowo – np. wielokrotnie zamieniając miejscami dwie losowo wybrane literki. W efekcie otrzymamy tabelkę szyfrowania.
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
I | L | D | N | S | E | W | M | C | H | P | R | O | F | X | G | V | A | U | Q | J | Y | B | Z | K | T |
Aby zaszyfrować tekst, podmieniamy literki z górnego wiersza odpowiadającymi im literami wiersza dolnego:
WIRXGREIFENXANXENDE (niem. –
ATAKUJEMY STOP, spacje zastąpiliśmy znakiem X) BCUZWASCESFZIFZSFNS |
Prosty szyfr podstawieniowy można łatwo złamać – np. wykorzystując informację
o statystycznej częstości występowania poszczególnych liter w danym języku. Te same znaki są zastępowane zawsze tą samą literą szyfru – np. tekst
DDDDD
zostanie zaszyfrowany jako NNNNN. Zastosujmy zatem prostą modyfikację. Tabelkę
szyfrowania zwińmy w pierścień – za
… | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | … |
… | Z | K | T | I | L | D | N | S | E | W | M | C | H | P | R | O | F | X | G | V | A | U | Q | J | Y | B | Z | K | T | I | L | D | … |
Umówmy się następnie, iż pierścień szyfrujący może się obracać wokół swojej
osi. Nad pierścieniem umieśćmy nieruchome litery
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
… | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | … |
… | Z | K | T | I | L | D | N | S | E | W | M | C | H | P | R | O | F | X | G | V | A | U | Q | J | Y | B | Z | K | T | I | L | D | … |
Gdy pierścień szyfrujący znajduje się w pokazanym powyżej położeniu, to otrzymujemy szyfr podstawowy pierścienia:
A → A →
I B → B → L C → C → D … |
Obróćmy teraz pierścień szyfrujący o jedną pozycję w lewo, tak aby pod stałą
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
… | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | … |
… | K | T | I | L | D | N | S | E | W | M | C | H | P | R | O | F | X | G | V | A | U | Q | J | Y | B | Z | K | T | I | L | D | N | … |
Teraz sposób szyfrowania tego układu zmienia się:
A → B
→
L B → C → D C → D → N … |
Dalej umówmy się, iż pierścień szyfrujący obraca się o jedną pozycję w lewo
po zaszyfrowaniu każdej litery. Ponieważ sposób szyfrowania się zmienia, to ciąg
tych samych liter nie zostanie już zaszyfrowany w ten sam znak. Sprawdź, iż przy
początkowym ustawieniu pierścienia szyfrującego
Jeden ruchomy pierścień szyfrujący nie daje odpowiednio dużej kombinacji szyfrów – tylko 26 różnych alfabetów podmieniających. Jeśli jednak dodamy drugi pierścień szyfrujący (wg innego szyfru podstawieniowego), na którego wejście wprowadzimy wyjście z pierwszego pierścienia, to liczba kombinacji alfabetów wzrośnie do:
26×26 = 676 |
Drugi pierścień wykonuje obrót o jedną pozycję, gdy pierścień pierwszy wykona pełen obrót – podobnie jak w mechanizmie licznikowym. Wtedy otrzymamy wszystkie kombinacje alfabetów pierwszego pierścienia z alfabetami pierścienia drugiego. Dodanie trzeciego pierścienia szyfrującego zwiększy liczbę szyfrów do:
26×26×26 = 17576 |
W czasie trwania II Wojny Światowej armia niemiecka posługiwała się powszechnie elektryczno-mechaniczną maszyną szyfrującą zwaną Enigma (z łac. tajemnica). Zasada działania oparta była o opisane powyżej szyfry podstawieniowe. Elementem szyfrującym w maszynie były specjalne, ruchome pierścienie szyfrujące.
Pierścienie Enigmy wyposażone były z obu stron w kontakty elektryczne. Na powyższej fotografii widzimy tylko jedną stronę pierścienia. Kontakty są okrągłymi blaszkami rozmieszczonymi wzdłuż obwodu pierścienia. Z drugiej, niewidocznej strony umieszczone były identyczne kontakty. Kontakty z obu stron łączono przewodami w pary. Każdy kontakt odpowiadał jednej literze alfabetu. Sposób połączenia kontaktów z jednej strony pierścienia z kontaktami po drugiej stronie określał sposób szyfrowania przez pierścień.
Jeśli do wybranego kontaktu po jednej stronie pierścienia doprowadzimy napięcie elektryczne, to pojawi się ono po drugiej stronie na kontakcie połączonym w pierścieniu przewodem elektrycznym z pierwszym kontaktem. W maszynie Enigma kontakty kolejnych trzech pierścieni szyfrujących były połączone ze sobą za pomocą sprężystych styków. Zatem napięcie na wyjściu pierwszego pierścienia przenosiło się dalej na wejście kolejnego, itd. Na powyższym rysunku drogę przepływu prądu przez pierścienie zaznaczono czerwonymi liniami.
Na końcu układu pierścieni znajdował się tzw. bęben odwracający, który
posiadał kontakty tylko po jednej stronie. Łączyły się one z kontaktami
wyjściowymi trzeciego pierścienia szyfrującego. Kontakty bębna odwracającego
połączone były w pary za pomocą przewodów elektrycznych. Zatem prąd
wchodzący do jednego kontaktu pojawiał się na innym kontakcie bębna
odwracającego i wracał z powrotem do trzeciego pierścienia szyfrującego, a stąd dalej poprzez pierścienie dwa i jeden wychodził na kontakt wejściowy
pierwszego pierścienia, skąd dalej zapalał żarówkę podświetlającą literkę na blacie maszyny Enigma. Droga powrotna prądu zaznaczona jest liniami
niebieskimi. W tym układzie
Dzięki zastosowaniu bębna odwracającego szyfr Enigmy stał się szyfrem
symetrycznym. Zwróć uwagę, iż jeśli w powyższym układzie pierścieni
szyfrujących wpuścimy prąd
W maszynach Enigma stosowano 10 różnych pierścieni szyfrujących. Poniższa tabela przedstawia ich sposoby szyfrowania.
Permutacje wprowadzane przez pierścienie | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Litery wejściowe |
A |
B |
C |
D |
E |
F |
G |
H |
I |
J |
K |
L |
M |
N |
O |
P |
Q |
R |
S |
T |
U |
V |
W |
X |
Y |
Z |
Pierścień I |
E |
K |
M |
F |
L |
G |
D |
Q |
V |
Z |
N |
T |
O |
W |
Y |
H |
X |
U |
S |
P |
A |
I |
B |
R |
C |
J |
Pierścień II |
A |
J |
D |
K |
S |
I |
R |
U |
X |
B |
L |
H |
W |
T |
M |
C |
Q |
G |
Z |
N |
P |
Y |
F |
V |
O |
E |
Pierścień III |
B |
D |
F |
H |
J |
L |
C |
P |
R |
T |
X |
V |
Z |
N |
Y |
E |
I |
W |
G |
A |
K |
M |
U |
S |
Q |
O |
Pierścień IV |
E |
S |
O |
V |
P |
Z |
J |
A |
Y |
Q |
U |
I |
R |
H |
X |
L |
N |
F |
T |
G |
K |
D |
C |
M |
W |
B |
Pierścień V |
V |
Z |
B |
R |
G |
I |
T |
Y |
U |
P |
S |
D |
N |
H |
L |
X |
A |
W |
M |
J |
Q |
O |
F |
E |
C |
K |
Pierścień VI |
J |
P |
G |
V |
O |
U |
M |
F |
Y |
Q |
B |
E |
N |
H |
Z |
R |
D |
K |
A |
S |
X |
L |
I |
C |
T |
W |
Pierścień VII |
N |
Z |
J |
H |
G |
R |
C |
X |
M |
Y |
S |
W |
B |
O |
U |
F |
A |
I |
V |
L |
P |
E |
K |
Q |
D |
T |
Pierścień VIII |
F |
K |
Q |
H |
T |
L |
X |
O |
C |
B |
J |
S |
P |
D |
Z |
R |
A |
M |
E |
W |
N |
I |
U |
Y |
G |
V |
Pierścień Beta |
L |
E |
Y |
J |
V |
C |
N |
I |
X |
W |
P |
B |
Q |
M |
D |
R |
T |
A |
K |
Z |
G |
F |
U |
H |
O |
S |
Pierścień Gamma |
F |
S |
O |
K |
A |
N |
U |
E |
R |
H |
M |
B |
T |
I |
Y |
C |
W |
L |
Q |
P |
Z |
X |
V |
G |
J |
D |
W powszechnym użyciu były
Lewa strona pierścienia szyfrującego Enigmy. Z boku widoczny jest karb przeniesienia. |
Prawa strona pierścienia szyfrującego Enigmy. Widoczna jest zębatka napędowa oraz kontakty. |
W poniższej tabeli przedstawiono położenie karbu w pierścieniach szyfrujących Enigmy.
Punkt przeniesienia obrotu | |
---|---|
Pierścień I | przy R |
Pierścień II | przy F |
Pierścień III | przy W |
Pierścień IV | przy K |
Pierścień V | przy A |
Pierścienie VI, VII oraz VIII | przy A i przy N |
Dane w tabeli należy rozumieć następująco:
W blacie Enigmy znajdowały się prostokątne otworki, poprzez które widoczne były litery wygrawerowane na obwodzie każdego pierścienia szyfrującego (później zamiast liter stosowano liczby 01…26). Poniższe zdjęcie przedstawia widok pierścieni szyfrującej Enigmy stosowanej przez Abwehrę (wywiad wojskowy) i Kriegsmarine (marynarka wojenna), w której stosowano 4 pierścienie zamiast 3 używanych przez Enigmy Wehrmachtu.
Załóżmy, iż pierwszym od prawej pierścieniem szyfrującym był
pierścień I. Otóż gdy w okienku pojawiła się dla tego pierścienia
W nowszych Enigmach punkt przeniesienia można było obracać na obwodzie pierścienia, co dodatkowo komplikowało system szyfrowania.
W poniższej tabelce zebraliśmy parametry bębnów odwracających, używanych w Armii Niemieckiej. Bębny były nieruchome, nie posiadały zatem mechanizmu przenoszenia napędu (w niektórych modelach Enigmy można jednak było je obracać ręcznie, co wprowadzało dodatkową modyfikację szyfru).
Zamiany liter wprowadzane przez bębny odwracające | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Litery wejściowe |
A |
B |
C |
D |
E |
F |
G |
H |
I |
J |
K |
L |
M |
N |
O |
P |
Q |
R |
S |
T |
U |
V |
W |
X |
Y |
Z |
Bęben B |
Y |
R |
U |
H |
Q |
S |
L |
D |
P |
X |
N |
G |
O |
K |
M |
I |
E |
B |
F |
Z |
C |
W |
V |
J |
A |
T |
Bęben C |
F |
V |
P |
J |
I |
A |
O |
Y |
E |
D |
R |
Z |
X |
W |
G |
C |
T |
K |
U |
Q |
S |
B |
N |
M |
H |
L |
reflektor B Dünn |
E |
N |
K |
Q |
A |
U |
Y |
W |
J |
I |
C |
O |
P |
B |
L |
M |
D |
X |
Z |
V |
F |
T |
H |
R |
G |
S |
reflektor C Dünn |
R |
D |
O |
B |
J |
N |
T |
K |
V |
E |
H |
M |
L |
F |
C |
W |
Z |
A |
X |
G |
Y |
I |
P |
S |
U |
Q |
Zwróć uwagę, iż bębny odwracające szyfrują w sposób symetryczny. Np. dla
Oprócz pierścieni maszyny Enigma posiadały tzw. łącznicę wtyczkową. Za pomocą przewodów z wtyczkami łącznica pozwalała na zamianę ze sobą par liter docierających z klawiatury Enigmy do pierścieni szyfrujących. Na obrazku widzimy, iż zamieniane są ze sobą litery:
Zamiana taka powoduje to, iż jeśli na klawiaturze naciśniemy np.
Projektowany przez nas symulator Enigmy będzie posiadał następujące elementy składowe (uwaga, symulator przybliża jedynie działanie Enigmy, nie stanowi jej dokładnego odpowiednika, aby zbytnio nie komplikować programów):
Wejście dla 26 liter
MORGENSXGREIFENXWIRXANXENDE = RANKIEM ATAKUJEMY STOP |
Wyjście dla 26 liter
Zespół trzech pierścieni szyfrujących, które można dowolnie konfigurować z pierścieni
Układ pierścieni będzie definiowany 3 cyfrową liczbą dziesiętną. Np. 351
oznacza, licząc od lewej do prawej, kolejno
Stan początkowy pierścieni (czyli to, co widać w okienkach
szyfrowych Enigmy) określany będzie trzyliterowym tekstem. Np.
FAD
oznacza (przy powyższym układzie pierścieni szyfrujących),
Łącznicę wtyczkową, która pozwala zamieniać ze sobą pary wybranych liter. W Enigmie stosowano 10 przewodów z wtyczkami, które umożliwiały dokonanie zamian 20 liter. Wszystkich możliwych permutacji jest 150738274937250. To właśnie dzięki łącznicy wtyczkowej Enigma posiadała tak wielką liczbę możliwych kodów, iż niemieccy kryptolodzy uznali za niemożliwe złamanie jej szyfru. Na szczęście dla nas mylili się, co w efekcie kosztowało Niemcy przegranie wojny.
Stan łącznicy wtyczkowej będziemy definiowali tekstem złożonym z par liter, które mają być zamienione miejscami. Np. tekst AXDSFE oznacza, iż zostaną ze sobą zamienione następujące litery:
A z X, D z S i F z E |
Zamiana liter występuje w dwóch miejscach:
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
Program odczytuje kolejno:
Wynikiem działania symulatora jest zaszyfrowany/rozszyfrowany tekst szyfrogramu. |
Pascal// Symulator Enigmy // Data: 20.08.2008 // (C)2020 mgr Jerzy Wałaszek //----------------------------- program prg; // definicje elementów Enigmy const pierscien_szyfr : array [1..5] of string = ( 'EKMFLGDQVZNTOWYHXUSPAIBRCJ', 'AJDKSIRUXBLHWTMCQGZNPYFVOE', 'BDFHJLCPRTXVZNYEIWGAKMUSQO', 'ESOVPZJAYQUIRHXLNFTGKDCMWB', 'VZBRGITYUPSDNHLXAWMJQOFECK'); przeniesienie : string = 'RFWKA'; beben_odwr : string = 'YRUHQSLDPXNGOKMIEBFZCWVJAT'; var pierscien : array [1..3] of integer; szyfr, s, lacznica : string; i, j, k, n : integer; c : char; ruch : boolean; begin // odczytujemy konfigurację pierścieni szyfrujących readln(n); for i := 3 downto 1 do begin // numer pierścienia na i-tej pozycji pierscien[i] := n mod 10; n := n div 10; end; // odczytujemy położenia początkowe pierścieni readln(szyfr); szyfr := upcase(szyfr); // odczytujemy stan łącznicy wtyczkowej readln(s); s := upcase(s); lacznica := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; i := 1; while i < length(s) do begin lacznica[ord(s[i])-64] := s[i+1]; lacznica[ord(s[i+1])-64] := s[i]; inc(i, 2); end; // odczytujemy szyfrogram readln(s); s := upcase(s); // szyfrujemy/rozszyfrowujemy szyfrogram for i := 1 to length(s) do begin // najpierw ruch pierścieni szyfrujących ruch := true; j := 3; while ruch and (j > 0) do begin ruch := szyfr[j]+przeniesienie[pierscien[j]]; szyfr[j] := chr(65+(ord(szyfr[j])-64) mod 26); dec(j); end; // pobieramy znak szyfrogramu c := s[i]; // przechodzimy przez łącznicę wtyczkową c := lacznica[ord(c)-64]; // przechodzimy przez pierścienie // w kierunku do bębna odwracającego for j := 3 downto 1 do begin k := ord(szyfr[j])-65; c := pierscien_szyfr[pierscien[j]][1+(ord(c)-65+k) mod 26]; c := chr(65+(ord(c)-39-k) mod 26); end; // przechodzimy przez bęben odwracający c := beben_odwr[ord(c)-64]; // wracamy ścieżką powrotną for j := 1 to 3 do begin k := ord(szyfr[j])-65; c := chr(65+(ord(c)-65+k) mod 26); n := 1; while pierscien_szyfr[pierscien[j]][n] <> c do inc(n); c := chr(65+(25+n-k) mod 26); end; // przechodzimy przez łącznicę wtyczkową c := lacznica[ord(c)-64]; // uaktualniamy szyfrogram s[i] := c; end; // wyświetlamy szyfrogram writeln(s); writeln; end. |
// Symulator Enigmy // Data: 22.08.2008 // (C)2020 mgr Jerzy Wałaszek //----------------------------- #include <iostream> #include <string> using namespace std; // definicje elementów Enigmy const string pierscien_szyfr[5] = { "EKMFLGDQVZNTOWYHXUSPAIBRCJ", "AJDKSIRUXBLHWTMCQGZNPYFVOE", "BDFHJLCPRTXVZNYEIWGAKMUSQO", "ESOVPZJAYQUIRHXLNFTGKDCMWB", "VZBRGITYUPSDNHLXAWMJQOFECK"}; const string przeniesienie = "RFWKA"; const string beben_odwr = "YRUHQSLDPXNGOKMIEBFZCWVJAT"; int main() { int pierscien[3], i, j, k, n, c; bool ruch; string szyfr, s, lacznica; // odczytujemy konfigurację pierścieni szyfrujących cin >> n; for(i = 2; i >= 0; i--) { // numer pierścienia na i-tej pozycji pierscien[i] = (n%10)-1; n /= 10; } // odczytujemy położenia początkowe pierścieni cin >> szyfr; for(i = 0; i < szyfr.length(); i++) szyfr[i] = toupper(szyfr[i]); // odczytujemy stan łącznicy wtyczkowej cin >> s; for(i = 0; i < s.length(); i++) s[i] = toupper(s[i]); lacznica = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for(i = 0; i < s.length()-1; i += 2) { lacznica[s[i]-65] = s[i+1]; lacznica[s[i+1]-65] = s[i]; } // odczytujemy szyfrogram cin.ignore(256, '\n'); getline(cin, s); for(i = 0; i < s.length(); i++) s[i] = toupper(s[i]); // szyfrujemy/rozszyfrowujemy szyfrogram for(i = 0; i < s.length(); i++) { // najpierw ruch pierścieni szyfrujących for(ruch = true, j = 2; ruch && (j >= 0); j--) { ruch = (szyfr[j] == przeniesienie[pierscien[j]]); szyfr[j]= 65+(szyfr[j]-64)%26; } // pobieramy znak szyfrogramu c = s[i]; // przechodzimy przez łącznicę wtyczkową c = lacznica[c-65]; // przechodzimy przez pierścienie // w kierunku do bębna odwracającego for(j = 2; j >= 0; j--) { k = szyfr[j]-65; c = pierscien_szyfr[pierscien[j]][(c-65+k)%26]; c = 65+(c-39-k)%26; } // przechodzimy przez bęben odwracający c = beben_odwr[c-65]; // wracamy ścieżką powrotną for(j = 0; j < 3; j++) { k = szyfr[j]-65; c = 65+(c-65+k)%26; for(n = 0; pierscien_szyfr[pierscien[j]][n] != c; n++); c = 65+(26+n-k)%26; } // przechodzimy przez łącznicę wtyczkową c = lacznica[c-65]; // uaktualniamy szyfrogram s[i] = c; } // wyświetlamy szyfrogram cout << s << endl << endl; return 0; } |
Basic' Symulator Enigmy ' Data: 22.08.2008 ' (C)2020 mgr Jerzy Wałaszek '----------------------------- ' definicje elementów Enigmy Dim pierscien_szyfr (5) As String => {_ "", "EKMFLGDQVZNTOWYHXUSPAIBRCJ", _ "AJDKSIRUXBLHWTMCQGZNPYFVOE", _ "BDFHJLCPRTXVZNYEIWGAKMUSQO", _ "ESOVPZJAYQUIRHXLNFTGKDCMWB", _ "VZBRGITYUPSDNHLXAWMJQOFECK"} Dim przeniesienie As String = "RFWKA" Dim beben_odwr As String = "YRUHQSLDPXNGOKMIEBFZCWVJAT" Dim As String szyfr, s, lacznica Dim As Integer pierscien(3), i, j, k, n, c, ruch ' odczytujemy konfigurację pierścieni szyfrujących Input n For i = 3 To 1 Step -1 ' numer pierścienia na i-tej pozycji pierscien(i) = n Mod 10 n \= 10 Next ' odczytujemy położenia początkowe pierścieni Input szyfr szyfr = Ucase(szyfr) ' odczytujemy stan łącznicy wtyczkowej Input s s = Ucase(s) lacznica = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" For i = 1 To Len(s)-1 Step 2 Mid(lacznica, Asc(Mid(s, i, 1))-64, 1) = Mid(s, i+1, 1) Mid(lacznica, Asc(Mid(s, i+1, 1))-64, 1) = Mid(s, i, 1) Next ' odczytujemy szyfrogram Line Input s s = Ucase(s) ' szyfrujemy/rozszyfrowujemy szyfrogram For i = 1 To Len(s) ' najpierw ruch pierścieni szyfrujących ruch = 1: j = 3 While (ruch=1) And (j > 0) If Mid(szyfr, j, 1) <> Mid(przeniesienie, pierscien(j), 1) _ Then ruch = 0 Mid(szyfr, j, 1) = Chr(65+(Asc(Mid(szyfr, j, 1))-64) Mod 26) j -= 1 Wend ' pobieramy znak szyfrogramu c = Asc(Mid(s, i, 1)) ' przechodzimy przez łącznicę wtyczkową c = Asc(Mid(lacznica, c-64, 1)) ' przechodzimy przez pierścienie w kierunku ' do bębna odwracającego For j = 3 To 1 Step -1 k = Asc(Mid(szyfr, j, 1))-65 c = Asc(Mid(pierscien_szyfr(pierscien(j)), 1+(c-65+k) _ Mod 26, 1)) c = 65+(c-39-k) Mod 26 Next ' przechodzimy przez bęben odwracający c = Asc(Mid(beben_odwr, c-64, 1)) ' wracamy ścieżką powrotną For j = 1 To 3 k = Asc(Mid(szyfr, j, 1))-65 c = 65+(c-65+k) Mod 26 n = 1 While Asc(Mid(pierscien_szyfr(pierscien(j)), n, 1)) <> c n += 1 Wend c = 65+(25+n-k) Mod 26 Next ' przechodzimy przez łącznicę wtyczkową c = Asc(Mid(lacznica, c-64, 1)) ' uaktualniamy szyfrogram Mid(s, i, 1) = Chr(c) Next ' wyświetlamy szyfrogram Print s Print End |
Python
(dodatek)# Symulator Enigmy # Data: 29.03.2024 # (C)2024 mgr Jerzy Wałaszek #----------------------------- # definicje elementów Enigmy pierscien_szyfr = [ "EKMFLGDQVZNTOWYHXUSPAIBRCJ", "AJDKSIRUXBLHWTMCQGZNPYFVOE", "BDFHJLCPRTXVZNYEIWGAKMUSQO", "ESOVPZJAYQUIRHXLNFTGKDCMWB", "VZBRGITYUPSDNHLXAWMJQOFECK"] przeniesienie = "RFWKA" beben_odwr = "YRUHQSLDPXNGOKMIEBFZCWVJAT" # odczytujemy konfigurację pierścieni szyfrujących n = int(input()) pierscien = [0, 1, 2, 3] for i in reversed(range(3)): # numer pierścienia na i-tej pozycji pierscien[i] = (n%10)-1 n //= 10 # odczytujemy położenia początkowe pierścieni szyfr = input().upper() # odczytujemy stan łącznicy wtyczkowej s = input().upper() lacznica = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" for i in range(0, len(s)-1, 2): p1 = ord(s[i])-65 p2 = ord(s[i+1])-65 lacznica = lacznica[:p1]+s[i+1]+lacznica[p1+1:] lacznica = lacznica[:p2]+s[i]+lacznica[p2+1:] # odczytujemy szyfrogram s = input().upper() # szyfrujemy/rozszyfrowujemy szyfrogram for i in range(len(s)): # najpierw ruch pierścieni szyfrujących j = 2 ruch = True while ruch and (j >= 0): ruch = szyfr[j] == przeniesienie[pierscien[j]] szyfr = szyfr[:j]+chr(65+(ord(szyfr[j])-64)%26)+szyfr[j+1:] j -= 1 # pobieramy znak szyfrogramu c = s[i] # przechodzimy przez łącznicę wtyczkową c = lacznica[ord(c)-65] # przechodzimy przez pierścienie # w kierunku do bębna odwracającego for j in reversed(range(3)): k = ord(szyfr[j])-65 c = pierscien_szyfr[pierscien[j]][(ord(c)-65+k)%26] c = chr(65+(ord(c)-39-k)%26) # przechodzimy przez bęben odwracający c = beben_odwr[ord(c)-65] # wracamy ścieżką powrotną for j in range(3): k = ord(szyfr[j])-65 c = chr(65+(ord(c)-65+k)%26) n = 0 while pierscien_szyfr[pierscien[j]][n] != c: n += 1 c = chr(65+(26+n-k)%26) # przechodzimy przez łącznicę wtyczkową c = lacznica[ord(c)-65] # uaktualniamy szyfrogram s = s[:i]+c+s[i+1:] # wyświetlamy szyfrogram print(s) print() |
Wynik: |
123 ABC ABCD WIRXGEBENXAUFXENDE ASDIQXFZJGWONIMHOT |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2024 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone
pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.