Łapka LogoŁapka Infa
🔐
Algorytmy

Szyfr Przestawieniowy i Vigenere'a

Bardziej zaawansowana kryptografia. Jak zamieniać literki parami lub stosować szyfr podstawieniowy o zmiennym kluczu.

Zaawansowana Kryptografia (Przestawieniowy i Vigenere)

Oprócz Cezara, matura bardzo lubi rzucać nieco bardziej "praktycznymi" szyframi.


1. Szyfr Przestawieniowy (Zamiana Parami)

Najpopularniejszym wariantem z grupy przestawieniowych jest taki, w którym zamieniamy literki miejscami parami. Na przykład wyraz INFORMATYKA. Zostanie przepleciony w: NIFROMTAKYA (litera 1 zamienia się z 2, 3 z 4, i tak dalej). Pamiętaj: Jeśli wyraz ma nieparzystą liczbę liter, to ostatnia zostaje nietknięta!

Python

def szyfr_przestawieniowy(tekst):
    # Zmieniamy string na liste znaków (stringi sa mutowalne w C++, a w py nie)
    znaki = list(tekst)
    
    for i in range(0, len(znaki) - 1, 2):
        znaki[i], znaki[i+1] = znaki[i+1], znaki[i]
        
    return "".join(znaki)

print(szyfr_przestawieniowy("INFORMATYKA"))

C++

#include <iostream>
#include <string>
#include <algorithm> // Do funkcji swap
using namespace std;

string szyfrPrzestawieniowy(string tekst) {
    // Skaczemy co dwie literki (i += 2)
    for(int i = 0; i < tekst.length() - 1; i += 2) {
        swap(tekst[i], tekst[i+1]);
    }
    return tekst;
}

int main() {
    cout << szyfrPrzestawieniowy("INFORMATYKA") << endl; // NIFROMTAKYA
    return 0;
}

2. Szyfr Vigenère'a

Vigenère to taki "Szyfr Cezara na sterydach". W Cezarze mieliśmy jedną liczbę, np. k=3. W szyfrze Vigenère'a kluczem nie jest liczba, ale... całe słowo (hasło)!

Na przykład chcemy zaszyfrować słowo MATURA kluczem KOT.

  1. Hasło przedłużamy, aby było długości tekstu: KOTKOT.
  2. Bierzemy pierwszą literę M i przesuwamy ją o kod pierwszej litery klucza K.
  3. Bierzemy drugą literę A i przesuwamy o literę klucza O.

Python

def vigenere(tekst, haslo):
    wynik = ""
    for i in range(len(tekst)):
        if 'A' <= tekst[i] <= 'Z':
            przesuniecie = ord(haslo[i % len(haslo)]) - ord('A')
            nowa = chr(ord(tekst[i]) + przesuniecie)
            if nowa > 'Z':
                nowa = chr(ord(nowa) - 26)
            wynik += nowa
        else:
            wynik += tekst[i]
    return wynik

C++

#include <iostream>
#include <string>
using namespace std;

string vigenere(string tekst, string haslo) {
    string wynik = "";
    for (int i = 0; i < tekst.length(); i++) {
        if (tekst[i] >= 'A' && tekst[i] <= 'Z') {
            int przesuniecie = haslo[i % haslo.length()] - 'A';
            char nowa = tekst[i] + przesuniecie;
            if (nowa > 'Z') nowa -= 26;
            wynik += nowa;
        } else {
            wynik += tekst[i];
        }
    }
    return wynik;
}