Program szyfrujący można pobrać tutaj: szyfr_z_kluczem_exe
Działa na Windows 7+
Szyfr cezara opisany tutaj można łatwo złamać. im dłuższa jest wiadomość tym łatwiej ją rozszyfrować. Wystarczy policzyć liczebność poszczególnych liter i sprawdzić jakie liczby w danym języku najczęściej występują.
jak widzimy w języku polskim najczęściej występującymi literami są „a”,”e”,”i”,”o” wystarczy,że namierzymy jakąś pojedyńczą literę i ją dopasujemy do układanki. Układ w Szyfru cezara wyglądał następująco:
a , b, c , d , e , f , g , h , i , j , …. dla przesunięcia o 3 w prawo otrzymywaliśmy
x , y , z , a , b , c , d , e , f , g …. nasze „a” zamieniało się w „d”, „d” zamieniało się w „g” i tak dalej.
Tak więc na dłuższą metę system ten się nie sprawdzał. im więcej mamy tekstu za hasłowanego tym łatwiej go złamać. Lepszą metodą jest szyfr z kluczem. Polega on także na przesuwaniu liter ale sekwencja ich przesuwania jest zakodowana w kluczu.
Ustawmy nasze słowo kluczowe na „suzuki”, sprawdzamy teraz w swoim alfabecie na jakich pozycjach stoją litery naszego słowa. U mnie było to „18 , 21 , 24 , 21 , 11 , 9”. nasz klucz będzie szyfrował pierwszą literę przesuwając ją w prawo o 18 potem drugą przesuwając w prawo o 21 następną o 24 itd. zakodowanie wiadomości: „kocham kryptografie” przesunie nam nasze litery o:
KOCHAM KRYPTOGRAFIE
18,21,24,21,11,9 18,21,24,21,11,9,18,21,24,21,11,9
ELCELX ENYMFZANACWN
Fajne prawda. Tekst tak za hasłowany jest dużo trudniejszy do złamanie. Ale nie niemożliwy. Nasz program do szyfrowania będzie wyglądał tak:
Będzie on trochę bazował na kodzie z programu w tym dziale: „Szyfr Cezara” więc warto zapoznać się z jego budową. Układamy wszystkie elementy tak jak na obrazku powyżej. 8 TextBoxów w tym 5 z zaznaczonym MultiLine, i dwa przyciski „Button”. warto robić to na bazie programu opisanego we wcześniejszym poście „Szyfr Cezara”. zachowujemy obie funkcje i Enum:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
Public Enum LetterType a = 1 b = 2 c = 3 d = 4 e = 5 f = 6 g = 7 h = 8 i = 9 j = 10 k = 11 l = 12 m = 13 n = 14 o = 15 p = 16 r = 17 s = 18 t = 19 w = 20 u = 21 x = 22 y = 23 z = 24 End Enum Function zaszyfruj(ByVal litera As String, ByVal przesuniecie As Integer) If IsNumeric(litera) Then If litera + przesuniecie > 9 And litera + przesuniecie < 20 Then Return (litera + przesuniecie - 10).ToString ElseIf litera + przesuniecie > 19 And litera + przesuniecie < 30 Then Return (litera + przesuniecie - 20).ToString ElseIf litera + przesuniecie > 29 Then Return (litera + przesuniecie - 30).ToString Else Return (litera + przesuniecie).ToString End If Else For Each i As Integer In [Enum].GetValues(GetType(LetterType)) If litera = CType(i, LetterType).ToString Then If i + przesuniecie > 24 Then Return CType(i + przesuniecie - 24, LetterType).ToString Else Return CType(i + przesuniecie, LetterType).ToString End If End If Next End If End Function Function rozszyfruj(ByVal litera As String, ByVal przesuniecie As Integer) If IsNumeric(litera) Then If litera - przesuniecie < 0 And litera - przesuniecie >= -10 Then Return (litera - przesuniecie + 10).ToString ElseIf litera - przesuniecie < -10 And litera - przesuniecie >= -20 Then Return (litera - przesuniecie + 20).ToString ElseIf litera - przesuniecie < -20 Then Return (litera - przesuniecie + 30).ToString Else Return (litera - przesuniecie).ToString End If Else For Each i As Integer In [Enum].GetValues(GetType(LetterType)) If litera = CType(i, LetterType).ToString Then If i - przesuniecie <= 0 Then Return CType(i - przesuniecie + 24, LetterType).ToString Else Return CType(i - przesuniecie, LetterType).ToString End If End If Next End If End Function |
Sytuacja zmienia się trochę podczas przyciskania przycisku. wcześniej w naszej sentencji:
1 |
TextBox3.Text += zaszyfruj(elements, TrackBar1.Value).ToString |
nasze przesunięcie było stałe o wartość jaką miał TrackBar1. My chcemy aby ta wartość była zmienna (zależna od klucza). Najpierw musimy wydobyć z klucza informacje nam potrzebne. W tym celu zainicjujemy sobie tablice która będzie przechowywała nam cyfry (integer) odpowiednio dopasowane do naszego Enum. kod poniżej pokazuje nam jak to osiągnąć:
- Inicjujemy tablice
- Wyodrębniamy litery z TextBox4 (klucza)
- Sprawdzamy czy istnieje powiązanie między kluczem a Enum. Jeśli tak do naszej tablicy „klucz” wstawiamy odpowiednią cyfrę przypisaną dla niej w Enum.
- Dodajemy wyodrębnioną cyfrę z Enum do naszej tablicy
- Wypisujemy nasz klucz w formie cyfrowym w TextBox5.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click TextBox3.Clear() Dim klucz As New List(Of Integer) For Each letter As String In TextBox4.Text For Each i As Integer In [Enum].GetValues(GetType(LetterType)) If letter = CType(i, LetterType).ToString Then klucz.Add(CType(i, LetterType)) End If Next Next For Each listaKlucza As Integer In klucz TextBox5.Text += listaKlucza.ToString Next End Sub |
Po odpaleniu wszystko powinno działać. Sprawdźcie sami czy to działa. U mnie wyglądało to tak:
Teraz należy te liczby z tablicy wykorzystać do szyfrowania. Czyli tutaj:
1 |
TextBox3.Text += zaszyfruj(elements, 'czyfry z tablicy').ToString |
Najpierw dodamy sobie zmienną która będzie nam badała położenie na jakim znajdujemy się w tablicy:
1 |
Dim polozenieWKluczu As Integer = 0 |
Do elementów tablicy odwołujemy się w następujący sposób:
1 2 3 4 |
Dim klucz As New List(Of String) = {"ala", "gosia", "monika"} klucz(0) 'kryje wartość tablicy 'ala' klucz(1) 'kryje wartość 'gosia' |
Tak więc aktualne przesunięcie litery będzie odbywało się poprzez połączenie „klucza” i „polozenieWKluczu”.
1 |
klucz(polozenieWKluczu) 'da nam wartość aktualnego przesunięcia |
a zmianę przesunięcia będziemy kontrolować poprzez dodanie do naszego „polozenieWKluczu +=1”
Całość wygląda tak:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Dim polozenieWKluczu As Integer = 0 For Each elements As String In TextBox1.Text If elements = " " Then TextBox3.Text += " " TextBox6.Text += "_" Else If polozenieWKluczu > klucz.Count - 1 Then TextBox3.Text += zaszyfruj(elements, klucz(0)) TextBox6.Text += klucz(0).ToString + "'" polozenieWKluczu = 1 Else TextBox3.Text += zaszyfruj(elements, klucz(polozenieWKluczu)) TextBox6.Text += klucz(polozenieWKluczu).ToString + "'" polozenieWKluczu += 1 End If End If Next |
nasza pętla „IF” mówi, że jeżeli położenie klucza będzie większe niż ilość zawartych w nim cyfr należy do naszej zaszyfrowanej wiadomości dodać literę z przesunięciem „klucz(0)” i zacząć liczyć nasze „polozenieWKluczu” od 1. jeśli polożenie w kluczu nie nie jest większe od jego liczebności użyj przesunięcia klucz(polozenieWKluczu) i zwiększ „polozenieWKluczu” o jeden. ostatecznie wygląda to tak:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click TextBox3.Clear() Dim klucz As New List(Of Integer) For Each letter As String In TextBox4.Text For Each i As Integer In [Enum].GetValues(GetType(LetterType)) If letter = CType(i, LetterType).ToString Then klucz.Add(CType(i, LetterType)) End If Next Next For Each listaKlucza As Integer In klucz TextBox5.Text += listaKlucza.ToString + "," Next Dim polozenieWKluczu As Integer = 0 For Each elements As String In TextBox1.Text If elements = " " Then TextBox3.Text += " " TextBox6.Text += "_" Else If polozenieWKluczu > klucz.Count - 1 Then TextBox3.Text += zaszyfruj(elements, klucz(0)) TextBox6.Text += klucz(0).ToString + "'" polozenieWKluczu = 1 Else TextBox3.Text += zaszyfruj(elements, klucz(polozenieWKluczu)) TextBox6.Text += klucz(polozenieWKluczu).ToString + "'" polozenieWKluczu += 1 End If End If Next End Sub |
Kod do deszyfrowania jest analogiczny.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click TextBox2.Clear() Dim klucz As New List(Of Integer) For Each letter As String In TextBox4.Text For Each i As Integer In [Enum].GetValues(GetType(LetterType)) If letter = CType(i, LetterType).ToString Then klucz.Add(CType(i, LetterType)) End If Next Next For Each listaKlucza As Integer In klucz TextBox7.Text += listaKlucza.ToString + "," Next Dim polozenieWKluczu As Integer = 0 For Each elements As String In TextBox3.Text If elements = " " Then TextBox2.Text += " " TextBox8.Text += "_" Else If polozenieWKluczu > klucz.Count - 1 Then TextBox2.Text += rozszyfruj(elements, klucz(0)) TextBox8.Text += klucz(0).ToString + "'" polozenieWKluczu = 1 Else TextBox2.Text += rozszyfruj(elements, klucz(polozenieWKluczu)) TextBox8.Text += klucz(polozenieWKluczu).ToString + "'" polozenieWKluczu += 1 End If End If Next End Sub |
wygląda to tak:
a pełen kod pobieramy: szyfr_z_kluczem_poprawiony
obrazek pobrany ze strony: http://pl.wikipedia.org/wiki/Alfabet_polski