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ć algorytm szyfrujący i deszyfrujący dla szyfru Cezara |
Tekst: |
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 |
Szyfr |
D |
E |
F |
G |
H |
I |
J |
K |
L |
M |
N |
O |
P |
Q |
R |
S |
T |
U |
V |
W |
X |
Y |
Z |
? |
? |
? |
Jak widzisz, szyfrowanie
Tekst: |
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 |
Szyfr |
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 |
Zatem X szyfrujemy
Zaszyfrujmy szyfrem Cezara tekst KROKODYL AREK:
Tekst: |
K |
R |
O |
K |
O |
D |
Y |
L |
|
A |
R |
E |
K |
Szyfr |
N |
U |
R |
N |
R |
G |
B |
O |
|
D |
U |
H |
N |
KROKODYL AREK → NURNRGBO DUHN
Tekst
stał się nieczytelny. Przy rozszyfrowywaniu postępujemy odwrotnie: literę szyfru
zastępujemy literą leżącą w alfabecie o trzy pozycje wcześniej. Tutaj podobnie
musimy zawinąć alfabet, aby przed
Szyfr |
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 |
Tekst: |
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 |
Otrzymaliśmy szyfr: DWDNXMHPB:
Szyfr |
D |
W |
D |
N |
X |
M |
H |
P |
B |
Tekst: |
A |
T |
A |
K |
U |
J |
E |
M |
Y |
DWDNXMHPB → ATAKUJEMY
Przejdźmy do szczegółów technicznych. Szyfrowanie będzie polegało na zamianie kodu ASCII znaku tekstu na kod ASCII znaku szyfru. Wykorzystamy operację modulo, ponieważ pozwoli ona nam zawijać kody liter.
Najpierw omówimy operacje dodawania i odejmowania modulo (reszta z dzielenia całkowitoliczbowego-operator %).
Operacja a mod m (a modulo m)
daje w wyniku resztę z dzielenia całkowitoliczbowego
16 mod 3 = 1
3 mieści się całkowitą liczbę razy
3 mod 5 = 15 i do 16 brakuje 1
1 jest tym, co
pozostaje po odjęciu
10 mod 3 = 1, bo 10-3×3 = 10- 9 = 1 10 mod 4 = 2, bo 10-2×4 = 10- 8 = 2 10 mod 5 = 0, bo 10-2×5 = 10-10 = 0 10 mod 6 = 4, bo 10-1×6 = 10- 6 = 4
Drugi argument operatora
% nazywamy modułem. Reszta z dzielenia jest zawsze mniejsza od
modułu. Dlaczego? Bo gdyby była równa lub większa, to by oznaczało, iż moduł
mieści się więcej razy w dzielonej liczbie. Zobaczmy wszystkie reszty z dzielenia różnych liczb przez moduł
13 mod 6 = 1 (13-2×6 = 13-12 = 1) 20 mod 6 = 2 (20-3×6 = 20-18 = 2) 27 mod 6 = 3 (27-4×6 = 27-24 = 3) 34 mod 6 = 4 (34-5×6 = 34-30 = 4) 41 mod 6 = 5 (41-6×6 = 41-36 = 5) 48 mod 6 = 0 (48-6×8 = 48-48 = 0)
Reszta z
dzielenia może przyjąć wartości:
Reszta z
dzielenia jest
Jeśli pierwszym argumentem operatora mod jest wyrażenie
(a+b) mod m = 0…m-1
Dodawanie poddane działaniu reszty z
dzielenia nazywamy
… (5+3) mod 10 = 8 (6+3) mod 10 = 9 (7+3) mod 10 = 0 (8+3) mod 10 = 1 (9+3) mod 10 = 2 …
Jak to zastosować do szyfrowania szyfrem Cezara? Prześledź poniższe wyprowadzenie:
Mamy kod znaku t z tekstu Ma on zakres
t' ← t-65
Za moduł przyjmujemy liczbę
Teraz dodajemy 3, czyli przesuwamy się o 3 pozycje do przodu. W wyniku dostaniemy wartości 3…28:
t" ← t'+3
Jest to nasza suma, poddajemy ją operacji
t''' ← t" mod 26
I wracamy z powrotem do kodu ASCII:
t'''' ← t'''+65
Złóżmy to w jedno wyrażenie i otrzymamy wzór na kod znaku szyfru
c ← (t-65+3) mod 26+65 c ← (t-62) mod 26+65
Sprawdźmy:
t = kod(G) = 71 c = (71-62) mod 26+65 c = 9 mod 26+65 c = 9+65 c = 74:kod litery J
t = kod(Y) = 89 c = (89-62) mod 26+65 c = 27 mod 26+65 c = 1+65 c = 66:kod litery B
Jeśli pierwszym argumentem operatora mod będzie wyrażenie
(a-b) mod m = -m+1…m-1
Aby pozbyć się wartości ujemnych, do różnicy
(a-b+m) mod m = 0…m-1
Jest to prawdziwe, gdy
Sprawdźmy,
…
(0-3+10) mod 10 = 7
(1-3+10) mod 10 = 8
(2-3+10) mod 10 = 9
(3-3+10) mod 10 = 0
(4-3+10) mod 10 = 1
…
Tutaj postępujemy podobnie jak przy szyfrowaniu, mamy kod
c' ← c-65
Odejmujemy 3, aby przesunąć kod
c" ← c'-3+26 c" ← c'+23
Teraz operacja reszty z dzielenia
c''' ← c'' mod 26
Wracamy z powrotem do kodu ASCII:
c'''' ← c'''+65
Składamy wzór:
t = (c-65-3+26) mod 26+65 t = (c-42) mod 26+65
Sprawdźmy:
c = Kod(G) = 71 t = (71-42) mod 26+65 t = 29 mod 26+65 t = 3+65 t = 68:kod litery D
c = Kod(B) = 66 t = (66-42) mod 26+65 t = 24 mod 26+65 t = 24+65 t = 89:kod litery Y
Szyfrowanie: c ← (t-62) mod 26+65
Rozszyfrowywanie: t = (c-42) mod 26+65
Teraz jesteśmy gotowi do konstrukcji algorytmu.
K01: Dla i = 0, 1, …, |s|-1: ; przeglądamy kolejne znaki tekstu wykonuj kroki K02…K03 K02: Jeśli (s[i] < "A") ∨ (s[i] > "Z"), ; pomijamy znaki nie będące literami A…Z to następny obieg pętli K01 K03: s[i] ← znak(65+(kod(s[i])-62) mod 26) ; szyfrujemy szyfrem Cezara K04: Pisz s ; wypisujemy szyfr K05: Zakończ
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 wiersz znaków. Zamienia litery małe na duże i szyfruje kodem Cezara wyświetlając wynik. |
Pascal// Szyfrowanie Kodem Cezara // Data: 18.08.2008 // (C)2020 mgr Jerzy Wałaszek //--------------------------- program prg; var s : string; i : integer; begin // odczytujemy wiersz znaków readln(s); // zamieniamy małe litery na duże s := upcase(s); // tekst kodujemy szyfrem Cezara for i := 1 to length(s) do if s[i] in ['A'..'Z'] then s[i] := chr(65+(ord(s[i])-62) mod 26); // wypisujemy zaszyfrowany tekst writeln(s); writeln; end. |
// Szyfrowanie Kodem Cezara // Data: 18.08.2008 // (C)2020 mgr Jerzy Wałaszek //--------------------------- #include <iostream> #include <string> using namespace std; int main() { string s; int i; // odczytujemy wiersz znaków getline(cin, s); // zamieniamy małe litery na duże // i kodujemy szyfrem cezara for(i = 0; i < s.length(); i++) { s[i] = toupper(s[i]); if((s[i] >= 'A') && (s[i] <= 'Z')) s[i] = char(65+(s[i]-62)%26); } // wypisujemy zaszyfrowany tekst cout << s << endl << endl; return 0; } |
Basic' Szyfrowanie Kodem Cezara ' Data: 18.08.2008 ' (C)2020 mgr Jerzy Wałaszek '--------------------------- Dim As String s Dim As Integer i ' odczytujemy wiersz znaków Line Input s ' zamieniamy małe litery na duże s = Ucase(s) ' tekst kodujemy szyfrem Cezara For i = 1 To Len(s) If Mid(s, i, 1) >= "A" And _ Mid(s, i, 1) <= "Z" Then _ Mid(s, i, 1) = Chr(65+(Asc(Mid(s, i, 1))- 62) Mod 26) Next ' wypisujemy zaszyfrowany tekst Print s Print End |
Python
(dodatek)# Szyfrowanie Kodem Cezara # Data: 24.03.2024 # (C)2024 mgr Jerzy Wałaszek #--------------------------- # odczytujemy wiersz znaków s = input() # zamieniamy małe litery na duże s = s.upper() # kodujemy szyfrem cezara for i in range(len(s)): if (s[i] >= "A") and (s[i] <= "Z"): s = s[:i]+chr(65+(ord(s[i])-62)%26)+s[i+1:] # wypisujemy zaszyfrowany tekst print(s) print() |
Wynik: |
nieprzyjaciel jest bardzo blisko QLHSUCBMDFLHO MHVW EDUGCR EOLVNR |
Łańcuch tekstowy s zaszyfrowany kodem Cezara.
Tekst jawny.
i | : | indeks; i ∈ N. |
kod(x) | : | zwraca kod |
znak(x) | : | zamienia kod x na odpowiadający mu znak ASCII. |
K01: Dlai = 0, 1, …, |s |-1: ; przetwarzamy kolejne znaki tekstu wykonuj kroki K02…K03 K02: Jeśli(s [i ] < "A") ∨ (s [i ] > "Z"), ; pomijamy znaki nie to następny obieg pętli K01 ; będące literami A…Z K03:s [i ] ← znak(65+(kod(s [i ]-42) mod 26) ; deszyfrujemy K04: Piszs K05: Zakończ
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 wiersz znaków zaszyfrowanych szyfrem Cezara, deszyfruje je i wypisuje tekst jawny. |
Pascal// Deszyfrowanie Kodu Cezara // Data: 18.08.2008 // (C)2020 mgr Jerzy Wałaszek //--------------------------- program prg; var s : string; i : integer; begin // odczytujemy wiersz znaków readln(s); // zamieniamy małe litery na duże s := upcase(s); // rozszyfrowujemy for i := 1 to length(s) do if s[i] in ['A'..'Z'] then s[i] := chr(65+(ord(s[i])-42) mod 26); // wypisujemy rozszyfrowany tekst writeln(s); writeln; end. |
// Deszyfrowanie Kodu Cezara // Data: 18.08.2008 // (C)2020 mgr Jerzy Wałaszek //--------------------------- #include <iostream> #include <string> using namespace std; int main() { string s; int i; // odczytujemy wiersz znaków getline(cin, s); // zamieniamy małe litery na duże // i rozszyfrowujemy for(i = 0; i < s.length(); i++) { s[i] = toupper(s[i]); if((s[i] >= 'A') && (s[i] <= 'Z')) s[i] = char(65+(s[i]-42)%26); } // wypisujemy rozszyfrowany tekst cout << s << endl << endl; return 0; } |
Basic' Deszyfrowanie Kodu Cezara ' Data: 18.08.2008 ' (C)2020 mgr Jerzy Wałaszek '--------------------------- Dim As String s Dim As Integer i ' odczytujemy wiersz znaków Line Input s ' zamieniamy małe litery na duże s = Ucase(s) ' rozszyfrowujemy For i = 1 To Len(s) If Mid(s, i, 1) >= "A" And Mid(s, i, 1) <= "Z" Then _ Mid(s, i, 1) = Chr(65+(Asc(Mid(s, i, 1))-42) Mod 26) Next ' wypisujemy rozszyfrowany tekst Print s Print End |
Python
(dodatek)# Deszyfrowanie Kodu Cezara # Data: 25.03.2024 # (C)2024 mgr Jerzy Wałaszek #--------------------------- # odczytujemy wiersz znaków s = input() # zamieniamy małe litery na duże s = s.upper() # i rozszyfrowujemy for i in range(len(s)): if(s[i] >= "A") and (s[i] <= "Z"): s = s[:i]+chr(65+(ord(s[i])-42)%26)+s[i+1:] # wypisujemy rozszyfrowany tekst print(s) print() |
Wynik: |
QLHSUCBMDFLHO MHVW EDUGCR EOLVNR NIEPRZYJACIEL JEST BARDZO BLISKO |
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.