Princip Caesarovy šifry
Princip Caesarovy šifry je založen na tom, že všechna písmena zprávy jsou během šifrování zaměněna za písmeno, které se abecedně nachází o pevně určený počet míst dále (tj. posun je pevně zvolen).
Počet možných variant klíče této šifry je o jedna menší než počet písmen (znaků) v použité abecedě. Zvolíme-li hodnotu posunu stejnou, jako je počet znaků použité abecedy, bude zašifrovaná zpráva identická s předlohou. Vyšším posunem, například posunem s klíčem o jedna větší, než je počet písmen (znaků) abecedy, dostaneme zašifrovanou zprávu odpovídající prostému posunu o klíč jedna, takže použití klíče hodnoty vyšší než počet znaků abecedy nemá kryptografický význam. V některých pramenech se proto o Caesarových šifrách mluví jako o šifrách aditivních.
Použití
Tuto šifru používal pro vojenskou komunikaci Julius Caesar a popsal ji v Zápiscích o válce galské (odtud je odvozen její název). Caesar používal posun o tři místa, obecně je ale za Caesarovu šifru označováno jakékoli šifrování na principu prostého posunu písmen (znaků) o konstantní hodnotu. I když je tato šifra z dnešního hlediska snadno rozluštitelná a pro jednoduchost šifrování/dešifrování bývá často používána dětmi, Julius Caesar ji s úspěchem používal při svých vojenských taženích.
Pro „vážné“ úkoly se tato šifra dnes neužívá a slouží pouze k školním demonstracím slabin jednoduchých substitučních šifrovacích systémů. Hlavní a neodstranitelnou slabinou této šifry je, že každý konkrétní znak zdrojového textu odpovídá jednomu konkrétnímu znaku šifrovaného textu. Například u klíče velikosti 3 je každé písmeno A ze vstupu (zdroje) převedeno (zašifrováno) na písmeno D, každé písmeno B je zašifrováno na písmeno E atd., takže lze zašifrovaný text snadno při kryptoanalýze statisticky zpracovat na výskyt jednotlivých písmen v daném vstupním jazyce.
Formální zápis
Caesarovu šifru můžeme definovat pomocí modulární aritmetiky, protože posun písmene o k pozic můžeme zapsat pomocí modula. Pokud si nadefinujeme abecedu jako posloupnost čísel od 0 do 25, kde a=0, b=1, c=2, …, z=25, pak můžeme nadefinovat funkci \$Posun(o, k)\$, kde o je znak, který se bude šifrovat a k klíč, kterým bude text šifrován, takto:
\$Posun(o, k) = (o +k) \mod 26\$.
Funkci \$E_k(x)\$, která vrátí zašifrovaný text x pomocí klíče k nadefinujeme takto:
\$E_k(x) = Posun(x\[i], k)\$ pro všechna i menší nebo rovna než délka vstupního řetězce x,
kde x[i] znamená písmeno na i-té pozici.
Na popis dešifrování budeme potřebovat funkci \$PosunZpet(c, k)\$, která posune zašifrované písmeno c zpět o k písmen.
Nadefinujeme ji takto: \$PosunZpet(c, k) = (c - k + 26) mod 26\$.
Dešifrovací funkci pro klíč k a šifrový text x definujeme takto: \$D_k(x) = PosunZpet(x\[i], k)\$ pro všechna i menší nebo rovna než délka vstupního řetězce x.
Jak to Caesar používal
Bílý kotouč je pevný a žlutý kotouč je otočný. Klíč (nebo posun) se nastaví otáčením žlutého kotouče je rozdílem mezi bílým písmenem A a žlutým písmenem A. V našem obrázku je klíč \$k=10\$.
Odesílatel a příjemce zprávy mají každý svůj kotouč a musí se předem dohodnout na klíči (posunu).
Odesílatel, který šifruje, postupuje takto:
V na bílem kotouči najde písmeno otevřeného textu (které chce zašifrovat) a do šifrovaného textu zapíše odpovídající žluté písmeno. Takto postupuje s celým otevřeným textem písmeno po písmenu. Po dokončení práce otevřený text zničí a předá poslu šifrovaný text. Ten ho doručí příjemci.
Příjemce, který dešifruje, postupuje takto:
Čte postupně písmenko po písmenku šifrovaný text a pro každé písmenko šifrovaného textu udělá toto: Najde na žlutém kotouči příslušné písmeno šifrovaného textu a do rozšifrovaného textu zapíše odpovídající bílé písmeno.
Odesílatel a příjmence musí mít oba správně nastaveny kotouče, jinak to nebude fungovat.
Úkol
Naprogramujte v Pythonu jednoduchý program pro šifrování a dešifrování Caesarovou šifrou.
Řešení
Tomáš Forejtek
# implementace Caesarovy šifry
# (c) Tomáš Forejtek <forejtek.tomas@sspvc.cz>
#
def caesar_cipher(zprava, posun):
sifrovana_zprava = ""
abeceda = "AÁBCČDĎEÉFGHIÍJKLMNŇOÓPQRŘSŠTŤUÚŮVWXYÝZŽaábcčdďeéfghiíjklmnňoópqrřsštťuúůvwxyýzž0123456789,.:;!?"
for char in zprava:
if char in abeceda:
zaklad = abeceda.index(char)
sifrovana_zprava += abeceda[(zaklad + posun) % len(abeceda)]
else:
sifrovana_zprava += char
return sifrovana_zprava
while True:
print()
zprava = input("Zadejte zprávu k zašifrování nebo dešifrování: ")
print()
posun = int(input("Zadejte hodnotu posunu: "))
print()
akce = input("Zadejte 'sifrovat' pro zašifrování nebo 'desifrovat' pro dešifrování: ")
print()
if akce == "sifrovat":
sifrovana_zprava = caesar_cipher(zprava, posun)
print(f"Zašifrovaná zpráva: {sifrovana_zprava}")
print()
elif akce == "desifrovat":
desifrovana_zprava = caesar_cipher(zprava, -posun)
print(f"Dešifrovaná zpráva: {desifrovana_zprava}")
print()
else:
print("Špatná funkce")
print()
znova = input("Chcete šifrovat nebo dešifrovat znovu? Zadejte 'a' jako ano nebo 'n' jako ne: ")
if znova != 'a':
break
print()
input("Stiskněte jakoukoliv klávesu pro ukončení!!!")
Zdrojový kód: caesarova_sifra_tomas_forejtek.py
SHA256sum: 5e68e1b114251f1f7dc86b482a322f97d501c3171ff2443db9f20dbe87ccacce caesarovasifra_tomas_forejtek.py
SHA256 je jednosměrná hashovací funkce, de facto podpis. Pomocí ní můžeme ověřit, že soubor caesarovasifra_tomas_forejtek.py nebyl nijak změněn oproti originálu. Ověření na Linuxu: sha256sum caesarovasifra_tomas_forejtek.py Ověření na Windows 10: certutil -hasfile caesarovasifra_tomas_forejtek.py SHA256
Tomáš Divíšek
#Toto je program na Césarovu šifru
retezec=input("Zadejte slovo:")
posun=int(input("Zadejte posun:"))
print("Původní zpráva:", retezec)
zprava=""
#Cyklus projíždějící jednotlivé znaky:
for znak in retezec:
i=ord(znak)
i=i+posun
#Kontrola přečtení
if(i>ord("z")):
i=i-26
znak=chr(i)
zprava=zprava+znak
#Vypíše
print("Zašifrovaná zpráva:", zprava)
input()
Zdrojový kód: Césarova_šifra_Divíšek_Tomáš.py
SHA256sum: 2dbb4c592f4e78f209baa7964284e938359864ce5dc44d2b0e26b634749edc11 Césarova_šifra_Divíšek_Tomáš.py
Janek Lojda
retezec=input("zadejte slovo:")
posun=int(input("Zadejte posun:"))
print("Původní zpráva:",retezec)
zprava=""
for znak in retezec:
i=ord(znak)
i=i+posun
if(i>ord("z")):
i=i-26
znak=chr(i)
zprava=zprava+znak
print("Zašifrovaná zpráva:",zprava)
input()
Zdrojový kód: caesarova_sifra_Janek_Lojda.py
SHA256sum: 19510a054652e6b9ee51b075b0248706c40ab2d1898ba465431064129ee28009 caesarova_sifra_Janek_Lojda.py
Jaroslav Jiroušek
zprava = input ("Zadejte zpravu:")
posun = int(input("Zadejte posun:"))
print ("\nPůvodní zpráva:", zprava)
text =""
for znak in zprava:
i = ord(znak)
i += posun
if (i>ord("z")):
i = i - 26
znak = chr(i)
text += znak
print ("Zašifrovaná zpráva:", text)
input()
Zdrojový kód: caesarova_sifra_Jaroslav_Jiroušek.py
SHA256sum: 2f31a12655a524868ae9944f1349b4efd8847a66b1640e6721f59fd3a5182807 caesarova_sifra_Jaroslav_Jiroušek.py
Sergej Kučir
retezec=input("Zadejte slovo:")
posun=int(input("Zadejte posun:"))
print("Původní zpráva:", retezec)
zprava=""
for znak in retezec:
i=ord(znak)
i=i+posun
if(i>ord("z")):
i=i-26
znak=chr(i)
zprava=zprava+znak
print("Zašifrovaná zpráva:", zprava)
input()
Zdrojový kód: cesarova_sifra_kucyr.py
SHA256sum: d8671bee7cba08e5cc6f8abe1240bf23ec4a8e2c83ad1199fd670e8a641e6924 cesarova_sifra_kucyr.py
Bohdan Mich
retezec=input("Zadejte slovo:")
posun=int(input("Zadejte posun:"))
print("Původní zpráva:", retezec)
zprava=""
for znak in retezec:
i=ord(znak)
i=i+posun
if(i>ord("z")):
i=i-26
znak=chr(i)
zprava=zprava+znak
print("Zašifrovaná zpráva:", zprava)
input()
Zdrojový kód: cesarova_sifra_mikh.py
SHA256sum: d8671bee7cba08e5cc6f8abe1240bf23ec4a8e2c83ad1199fd670e8a641e6924 cesarova_sifra_mikh.py
Martin Částek
retezec=input("Zde napište slovo k zašifrování/rozšifrování:")
posun=int(input("Zadejte posun v plusu pro zašifrování a mínus pro rozšifrování:"))
print("Původní slovo", retezec)
zprava=""
for znak in retezec:
i=ord(znak)
i=i+posun
if(i>ord("z")):
i=i-26
znak=chr(i)
zprava=zprava+znak
print("Zašifrované/rozšifrované slovo:", zprava)
input()
Zdrojový kód: caesarova_sifra_castek.py
SHA256sum: ddf36bc220c2fa658d43db89e5f1b0a8028a10ab14dc536e98f3cf548628badd caesarova_sifra_castek.py
Matěj Svoboda
// Caesarova šifra
// (c) Matěj Svoboda <svoboda.matej@sspvc.cz>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace cezeravo_sifra
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Zadej text:");
string text = Console.ReadLine();
Console.WriteLine("Původní text: " + text);
string zprava = "";
Console.WriteLine("Zadejte šifru: ");
int sifra = int.Parse(Console.ReadLine());
foreach (char c in text)
{
int i = (int)c;
i += sifra;
char znak = (char)i;
zprava += znak;
}
Console.WriteLine(zprava);
Console.ReadKey();
}
}
}
Zdrojový kód a spustitelný soubor: cezarova-sifra.zip
SHA256sum: a819785829460a0f549f82810a29daa96db3594ade41fc0d756e170a5c8eca7a cezarova-sifra.zip
Dominik Marek
def encrypt_caesar(plaintext, shift):
ciphertext = ""
for char in plaintext:
if char.isalpha():
shift_char = chr((ord(char) + shift - 97) % 26 + 97)
ciphertext += shift_char
else:
ciphertext += char
return ciphertext
def decrypt_caesar(ciphertext, shift):
plaintext = ""
for char in ciphertext:
if char.isalpha():
shift_char = chr((ord(char) - shift - 97) % 26 + 97)
plaintext += shift_char
else:
plaintext += char
return plaintext
a=input("Zadejte text k zašifrování: ")
print(a)
shift = int(input("Zadejte posunutí: "))
ciphertext = encrypt_caesar(a, shift)
print("sifrovani: ", ciphertext)
decrypted_plaintext = decrypt_caesar(ciphertext, shift)
print("Zpět původní text: ", decrypted_plaintext)
Zdrojový kód: siffrovani.py
SHA256sum: 4c1603bfa0534cfa20b13c265fc568e20f487a5199ba105e728ef7f4c746a4d4 siffrovani.py
Jakub Valášek
def encrypt_caesar(plaintext, shift):
ciphertext = ""
for char in plaintext:
if char.isalpha():
shift_char = chr((ord(char) + shift - 97) % 26 + 97)
ciphertext += shift_char
else:
ciphertext += char
return ciphertext
def decrypt_caesar(ciphertext, shift):
plaintext = ""
for char in ciphertext:
if char.isalpha():
shift_char = chr((ord(char) - shift - 97) % 26 + 97)
plaintext += shift_char
else:
plaintext += char
return plaintext
# Example usage
a=input("Zadejte text")
print(a)
shift = 3
ciphertext = encrypt_caesar(a, shift)
print("Ciphertext:" , ciphertext)
decrypted_plaintext = decrypt_caesar(ciphertext, shift)
print("Decrypted plaintext:" , decrypted_plaintext)
Zdrojový kód: šifra_Jakub_Valášek.py
SHA256sum: acc2097b2923c4bb00b263dd278c849241715fa84ffdd901ff026fb3640e16ea šifra_Jakub_Valášek.py
Matěj Papež
def encode(text: str, key: int, abc: list[str] = None) -> str:
if abc is None:
abc = ['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']
new = ''
for char in text:
i = abc.index(char.lower())
while True:
if i + key >= len(abc):
i -= len(abc)
elif i + key < 0:
i += len(abc)
else:
break
if char.isupper():
new += abc[i + key].upper()
else:
new += abc[i + key]
return new
Zdrojový kód: ffffffffff.py
SHA256sum: 47915985dd60589b2880a2eb2e0a57115565329f57b22ec76a725580366e5311 ffffffffff.py
Anna Martinková
#Caesarova sifra
abc = "ABCDEFGHIJKLMNOPQRTUVWXYZ"
def encode(text, shift):
text2=""
for letter in text:
index=abc.index(letter)
index2=index+shift
index2=index2%26
text2+=abc[index2]
return text2
def decode(text,shift):
text2=""
print(encode("AHOJ",54))
Zdrojový kód: caesarova.py caesarova.zip
SHA256sum: 6f062005e3a42f6dd09a3d61dcee32555cefbbb0f4e097a88c8610f008cc33df caesarova.py
SHA256sum: 6e77505b61ae3a549f28c1db64c1939589f38122b8ca010bb1262683b7301439 caesarova.zip