|
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 |
©2026 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 od A do 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 | 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 literą Z będą występowały litery A, B, C…, – przed literą A znajdą się litery … 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 | … |
Umówmy się następnie, iż pierścień szyfrujący może się obracać wokół swojej osi. Nad pierścieniem umieśćmy nieruchome litery od A do Z. Poniżej przedstawiamy ten układ w rozwinięciu na płaszczyznę:
| 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łą literą A znalazła się litera B pierścienia:
| 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 A-A (pod stałą literą A jest litera A pierścienia) wyraz MAMA zostanie zaszyfrowany jako: OLXN.
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 literka C szyfrowana jest na literkę B.
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 stykiem B, to wyjdzie on stykiem C. Zatem ten sam klucz (wstępne położenie pierścieni szyfrujących) można stosować zarówno do szyfrowania jak i do deszyfrowania.
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 pierścienie I…V. Na obwodzie każdego pierścienia umieszczony był karb, dzięki któremu ruch pierścienia przenosił się w odpowiednim miejscu do pierścienia następnego. W celu utrudnienia identyfikacji pierścieni szyfrujących przez przeciwnika, karby umieszczano w różnych miejscach pierścieni (w rzeczywistości była to kryptologiczna pomyłka, która ułatwiała polskim kryptologom identyfikację zastosowanych pierścieni). Zasada działania układu przeniesienia napędu była podobna do układów mechanicznych liczników. Gdy pierwszy pierścień wykonał pełny obrót, to karb na jego obwodzie powodował zazębienie się specjalnej zapadki obracającej następny pierścień o 1/26 obwodu. W drugim pierścieniu identyczny układ obracał trzeci pierścień, gdy pierścień drugi wykonał pełny obrót.
![]() 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 literka R, to obrót pierścienia I powodował również obrót sąsiadującego po lewej pierścienia szyfrującego.
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 bębna B litera A przechodzi w Y oraz litera Y przechodzi w A. Spowodowane jest to tym, iż wewnątrz bębna pary kontaktów są połączone ze sobą przewodem. Zatem prąd wchodzący stykiem A zawsze pojawi się na styku Y i na odwrót.

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. klawisz A, to do pierścieni dotrze sygnał litery J. Podobnie gdy naciśniemy klawisz J, do pierścieni szyfrujących dotrze sygnał na styk A. Również prąd wychodzący stykiem A spowoduje zapalenie się lampki J i na odwrót. Dzięki łącznicy ilość możliwych do uzyskania kombinacji szyfrów osiągała astronomiczną liczbę 15 × 1018. Niemcy uważali, iż kod Enigmy jest niemożliwy do złamania. Jak dzisiaj wiemy, kod ten został złamany przez trzech polskich kryptologów: M. Rejewskiego, J. Różyckiego oraz H. Zygalskiego. Więcej na temat Enigmy znajdziesz w naszym artykule o komputerach Colossus.
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 od A do Z, które symuluje klawiaturę Enigmy. Na klawiaturze brak spacji oraz znaków przystankowych. W charakterze spacji niemieccy szyfranci stosowali nieużywaną w tekstach literę X:
MORGENSXGREIFENXWIRXANXENDE = RANKIEM ATAKUJEMY STOP |

Wyjście dla 26 liter od A do Z, które symuluje lampki Enigmy. Lampki zapalając się podświetlały od spodu literki będące wynikiem szyfrowania literek wprowadzonych do maszyny przy pomocy klawiatury.

Zespół trzech pierścieni szyfrujących, które można dowolnie konfigurować z pierścieni od i do V rzeczywistej Enigmy. Zachowamy tutaj sposób szyfrowania tych pierścieni. Pierścienie będą współpracowały z bębnem odwracającym typu B. Ten element nie będzie wymienny. W celu uproszczenia założymy również, iż punkty przeniesień dla poszczególnych pierścieni szyfrujących są stałe, zgodne z podaną wcześniej tabelą. W rzeczywistej Enigmie punkty te można było przemieszczać wraz z tarczą literową, co powodowało zmianę sposobu szyfrowania dla danego klucza.
Układ pierścieni będzie definiowany 3 cyfrową liczbą dziesiętną. Np. 351 oznacza, licząc od lewej do prawej, kolejno pierścień III, pierścień V oraz pierścień I. Dane są wprowadzane do pierścienia I, następnie przechodzą do pierścieni V i III, odbijają się w bębnie odwracającym i wracają poprzez pierścień III, V i I.
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), iż pierścień III należy ustawić na F, pierścień V na A i pierścień I na D.

Łą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. |
C++// 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 |
JavaScript<html>
<head>
<title>
ENIGMA
</title>
</head>
<body>
<div style="overflow-x: auto;"
align="center">
<table
border="0"
cellpadding="4"
style="border-collapse:
collapse">
<tr>
<td nowrap>
<form
name="frm"
style="text-align: center;
background-color:
#E7E7DA">
<b>Uproszczony symulator
Enigmy</b><br/>
(C)2026
mgr Jerzy Wałaszek
<hr>
Kolejność pierścieni
szyfrujących<br/>
<input
type="text"
name="inp_pierscien"
size="20"
value="123"
style="text-align:
center"><br/>
Ustawienia początkowe
pierścieni<br/>
<input
type="text"
name="inp_szyfr"
size="20"
value="ABC"
style="text-align:
center"><br/>
Stan połączeń łącznicy
wtyczkowej<br/>
<input
type="text"
name="inp_lacznica"
size="20"
value="ABCD"
style="text-align:
center">
<hr>
Szyfrogram<br/>
<input
type="text"
name="inp_s"
size="50"
value="WIRXGEBENXAUFXENDE"
style="text-align:
center">
<hr>
<input
type="button"
value="Uruchom Enigmę"
name="B1"
onclick="main();">
<hr>
<b>Wynik:</b>
<div id="out">
.
</div>
</form>
</td>
</tr>
</table>
</div>
<script language=javascript
type=text/javascript>
// Symulator Enigmy
// Data: 22.08.2008
// (C)2008 mgr Jerzy Wałaszek
//---------------------------
// definicje elementów Enigmy
//---------------------------
let pierscien_szyfr = new Array
("EKMFLGDQVZNTOWYHXUSPAIBRCJ",
"AJDKSIRUXBLHWTMCQGZNPYFVOE",
"BDFHJLCPRTXVZNYEIWGAKMUSQO",
"ESOVPZJAYQUIRHXLNFTGKDCMWB",
"VZBRGITYUPSDNHLXAWMJQOFECK");
let przeniesienie = "RFWKA";
let beben_odwr =
"YRUHQSLDPXNGOKMIEBFZCWVJAT";
// Program główny
//---------------
function main()
{
let pierscien = new Array(3);
let i,j,k,n,c,ruch,szyfr,
s,lacznica,t;
// odczytujemy konfigurację
// pierścieni szyfrujących
n = parseInt(document.frm
.inp_pierscien.value);
for(i = 2; i >= 0; i--)
{
// numer pierścienia
// na i-tej pozycji
pierscien[i] = (n % 10) - 1;
n = Math.floor(n / 10);
}
// odczytujemy położenia
// początkowe pierścieni
szyfr = document.frm
.inp_szyfr.value;
szyfr = szyfr.toUpperCase();
// odczytujemy stan
// łącznicy wtyczkowej
s = document.frm
.inp_lacznica.value;
s = s.toUpperCase();
lacznica =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for(i = 0;
i < s.length - 1;
i += 2)
{
lacznica = lacznica.substr
(0, s.charCodeAt(i) - 65) +
s.charAt(i + 1) +
lacznica.substr
(s.charCodeAt(i) - 64);
lacznica = lacznica.substr
(0, s.charCodeAt(i + 1) - 65) +
s.charAt(i) + lacznica.substr
(s.charCodeAt(i + 1) - 64);
}
// odczytujemy szyfrogram
s = document.frm.inp_s.value;
s = s.toUpperCase();
// szyfrujemy/rozszyfrowujemy
// szyfrogram
t = "";
for(i = 0; i < s.length; i++)
{
// najpierw ruch
// pierścieni szyfrujących
for(ruch = true, j = 2;
ruch && (j >= 0); j--)
{
ruch = (szyfr.charAt(j)
== przeniesienie
.charAt(pierscien[j]));
szyfr = szyfr.substr(0, j) +
String.fromCharCode
(65 + (szyfr.charCodeAt(j)
-64) % 26) + szyfr
.substr(j + 1);
}
// pobieramy znak szyfrogramu
c = s.charCodeAt(i);
// przechodzimy przez
// łącznicę wtyczkową
c = lacznica.charCodeAt(c - 65);
// przechodzimy przez
// pierścienie w kierunku
// do bębna odwracającego
for(j = 2; j>= 0; j--)
{
k = szyfr.charCodeAt(j) - 65;
c = pierscien_szyfr[pierscien[j]]
.charCodeAt((c - 65 + k) % 26);
c = 65 + (c - 39 - k) % 26;
}
// przechodzimy przez
// bęben odwracający
c = beben_odwr.charCodeAt(c - 65);
// wracamy ścieżką powrotną
for(j = 0; j < 3; j++)
{
k = szyfr.charCodeAt(j) - 65;
c = 65 + (c - 65 + k) % 26;
for(n = 0;
pierscien_szyfr[pierscien[j]]
.charCodeAt(n) != c;
n++);
c = 65 + (26 + n - k) % 26;
}
// przechodzimy przez
// łącznicę wtyczkową
c = lacznica.charCodeAt(c - 65);
// uaktualniamy szyfrogram
t += String.fromCharCode(c);
}
// wyświetlamy szyfrogram
document.getElementById("out")
.innerHTML = t
}
</script>
</body>
</html>
|
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 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.