Dataczwartek, 13 sierpnia 2026 Czas18:44:01
← Programowanie konsolowe (C#)

Lekcja 23. Algorytmy szyfrowania i tekstowe (szyfr Cezara, GADERYPOLUKI)

Średni

Po co się tego uczymy?

Podstawa programowa (INF.04.3.3) wymienia wprost "algorytmy tekstowe" i "algorytmy szyfrowania" jako coś, co trzeba umieć zaimplementować. To też świetny sposób na przećwiczenie pracy z tekstem (string) w C# — indeksowanie znaków, kody ASCII, pętle po znakach — czyli umiejętności przydatne w każdym programie przetwarzającym dane od użytkownika.

Teoria

Szyfr Cezara to jeden z najstarszych i najprostszych szyfrów podstawieniowych — każda litera tekstu jawnego jest zastępowana literą przesuniętą o stałą liczbę pozycji w alfabecie (tzw. klucz). Przy przesunięciu 3: A→D, B→E, C→F, itd. Po dotarciu do końca alfabetu przesunięcie "zawija się" na początek (X→A, Y→B, Z→C). Do deszyfrowania wystarczy przesunąć litery w przeciwną stronę o tę samą wartość.

GADERYPOLUKI to polski szyfr podstawieniowy, w którym litery alfabetu są zamieniane parami zgodnie ze słowem-kluczem GADERYPOLUKI: G↔A, D↔E, R↔Y, P↔O, L↔U, K↔I (litery łączone są w pary wg kolejności liter w tym słowie). Zasada działania jest identyczna jak w prostym szyfrze podstawieniowym — tylko reguła zamiany jest inna niż stałe przesunięcie.

W C# do pracy z pojedynczymi znakami tekstu przydają się: indeksowanie tekst[i] (dostęp do konkretnego znaku), typ char oraz fakt, że w C# znaki mają swoje kody liczbowe (ASCII/Unicode) — można je konwertować na liczby i z powrotem, co jest kluczowe przy przesuwaniu liter w szyfrze Cezara.

Schemat

Szyfr Cezara z przesunięciem 3:

Alfabet jawny:      A  B  C  D  E  F  G  H  I  J  K  ...
Alfabet zaszyfr.:   D  E  F  G  H  I  J  K  L  M  N  ...
                    (każda litera przesunięta o 3 miejsca w prawo)

Szyfrowanie "KOT":
  K -> N
  O -> R
  T -> W
Wynik: "NRW"

Deszyfrowanie: przesuwamy w drugą stronę (o 3 w lewo): N->K, R->O, W->T

Przykład z życia

Szyfr Cezara i podobne proste szyfry podstawieniowe nie są dziś używane do prawdziwego zabezpieczania danych (łamie się je w kilka sekund), ale sama IDEA podstawienia znaków leży u podstaw dużo poważniejszych systemów szyfrowania (np. AES, którego używa HTTPS przy każdym wejściu na stronę bankową). Zrozumienie prostego przypadku pomaga zrozumieć, na czym w ogóle polega szyfrowanie — zamiana czytelnej informacji na nieczytelną według znanego obu stronom klucza/reguły.

Kod (C#)

using System;
using System.Text;

class Program
{
    // Szyfr Cezara — działa tylko na wielkich literach A-Z dla uproszczenia.
    static string SzyfrCezara(string tekst, int przesuniecie)
    {
        var wynik = new StringBuilder();

        foreach (char znak in tekst)
        {
            if (znak >= 'A' && znak <= 'Z')
            {
                // 'A' ma kod 65. Odejmujemy go, żeby dostać pozycję 0-25,
                // dodajemy przesunięcie, bierzemy resztę z dzielenia przez 26
                // (żeby "zawinąć" po Z z powrotem na A), i wracamy do litery.
                int pozycja = (znak - 'A' + przesuniecie) % 26;
                wynik.Append((char)('A' + pozycja));
            }
            else
            {
                wynik.Append(znak); // spacje i inne znaki bez zmian
            }
        }

        return wynik.ToString();
    }

    static void Main()
    {
        string tajneSlowo = "PROGRAMOWANIE";
        string zaszyfrowane = SzyfrCezara(tajneSlowo, 3);
        string odszyfrowane = SzyfrCezara(zaszyfrowane, 26 - 3); // przesunięcie w drugą stronę

        Console.WriteLine($"Tekst jawny:    {tajneSlowo}");
        Console.WriteLine($"Zaszyfrowany:   {zaszyfrowane}");
        Console.WriteLine($"Odszyfrowany:   {odszyfrowane}");
    }
}

Komentarz i wyjaśnienie kodu

Najważniejsza linijka to (znak - 'A' + przesuniecie) % 26. Odejmowanie znaków w C# (znak - 'A') daje liczbę — różnicę ich kodów. Dla litery A da to 0, dla B da 1, itd. Po dodaniu przesunięcia bierzemy resztę z dzielenia przez 26 (liczba liter w alfabecie łacińskim), żeby po przekroczeniu Z "zawinąć" z powrotem na A. Na końcu (char)('A' + pozycja) zamienia tę liczbę z powrotem na literę. Deszyfrowanie to po prostu przesunięcie w drugą stronę — a przesunięcie "w drugą stronę o 3" to to samo co "do przodu o 26-3=23", dzięki czemu można użyć tej samej funkcji.

Ćwiczenie samodzielne

Zmień przesunięcie na inną wartość (np. 7 albo 13 — słynne ROT13) i sprawdź, czy szyfrowanie i deszyfrowanie nadal działają poprawnie dla tego samego tekstu.

Plac zabaw — wypróbuj online

Poniższy kod wykonuje się od razu w Twojej przeglądarce — nic nie trzeba instalować. Zmień kod i kliknij „Uruchom”.

CSHARP

Zadania do pracy własnej

  1. Rozszerz funkcję SzyfrCezara, żeby działała też dla małych liter (a-z), nie tylko wielkich.

  2. Napisz funkcję realizującą szyfr GADERYPOLUKI dla wielkich liter G, A, D, E, R, Y, P, O, L, U, K, I (pozostałe litery alfabetu zostają bez zmian). Podpowiedź: zbuduj słownik (Dictionary<char, char>) z parami zamian.

  3. Napisz program łamiący prosty szyfr Cezara metodą "brute force" — wypróbuj wszystkie 26 możliwych przesunięć na zaszyfrowanym tekście i wypisz wszystkie warianty, żeby użytkownik sam wybrał ten, który ma sens.

Typowe błędy

Zapominanie o "zawijaniu" alfabetu — bez operatora % (reszta z dzielenia) litera Z przesunięta o 3 dałaby znak spoza alfabetu zamiast wrócić na C.

Szyfrowanie znaków spoza zakresu A-Z — bez sprawdzenia if (znak >= 'A' && znak <= 'Z') spacje, cyfry i polskie znaki (ą, ę, ć) też zostałyby "przesunięte" i zmieniłyby się w bezsensowne symbole.

Mylenie kierunku przesunięcia przy deszyfrowaniu — trzeba pamiętać, że deszyfrowanie to przesunięcie o tę samą wartość, ale w przeciwnym kierunku.

Nawiązanie do egzaminu zawodowego

To bezpośrednia realizacja INF.04.3.3 — "algorytmy tekstowe, szyfrowania". Ten sam mechanizm indeksowania znaków i pracy z kodami liter przyda się też przy innych zadaniach tekstowych z arkuszy egzaminacyjnych (np. zliczanie wystąpień liter, sprawdzanie czy tekst jest palindromem, walidacja formatu wprowadzonych danych).