Witam wszystkich. Dzisiaj zajmiemy się szyfrowaniem hexów pliku. Jeśli sięgniemy bardzo głęboko do jakiegokolwiek pliku na komputerze to zobaczymy, że jest on zbudowany z samych 1 i 0 nazywamy to systemem binarnym, nie będe się tutaj zagłębiał w technologie informacyjną ale jeśli ktoś jest zainteresowany zapraszam do wikipedii aby poczytać więcej o systemie binarnym. Wracając do kryptografii kodowanie 1 i 0 mija się z celem , bo niby co zamienimy 0 na 1 a 1 na 0 to każdy sprytny magik zaraz to odkoduje. Aby zakodować nasz plik musimy pogrupować 1 i 0 w taki sposób aby można je było przekształcić w inny system metryczny. My zamienimy sobie bity (zbiór 8 znaków) naszego pliku na system szesnastkowy, co da nam wielki wachlarz możliwości. Wykorzystamy tutaj sposób kodowania z poprzedniego tutoriala o kodowaniu z kluczem który można przeczytać tutaj. Więcej o systemie szesnastkowym (heksadecymalnym w skrócie hex) można poczytać na wikipedii. Teraz troche teori jak to będzie wyglądać. Stworzymy sobie zwykły plik tekstowy a w nim zapiszemy swoje imię. jeśli nie wiecie jak rozkodować/zakodować swoje imię zapraszam na stronę tutaj.
Moje imię to „Piotrek” jego odzwierciedlenie binarne będzie wyglądać tak: 01010000 01101001 01101111 01110100 01110010 01100101 01101011 a w wersji hexowej tak: 50 69 6f 74 72 65 6b
Jak ja to przekształciłem. zbiór 8 znaków nazywamy bajtem, każdy bajt składa się więc z 2 hexów, podzieliłem bajt na pół i wyszło mi w pierwszym bajcie (patrz tabelka niżej) 0101 i 0000 co po odczytaniu w tabelce daje 0101 = 5 a 0000 = 0. W systemie szesnastkowym każda litera składa się z kombinacji czterech 1 i 0:
| 0hex | = | 0dec | = | 0oct | = | 0 | 0 | 0 | 0 |
| 1hex | = | 1dec | = | 1oct | = | 0 | 0 | 0 | 1 |
| 2hex | = | 2dec | = | 2oct | = | 0 | 0 | 1 | 0 |
| 3hex | = | 3dec | = | 3oct | = | 0 | 0 | 1 | 1 |
| 4hex | = | 4dec | = | 4oct | = | 0 | 1 | 0 | 0 |
| 5hex | = | 5dec | = | 5oct | = | 0 | 1 | 0 | 1 |
| 6hex | = | 6dec | = | 6oct | = | 0 | 1 | 1 | 0 |
| 7hex | = | 7dec | = | 7oct | = | 0 | 1 | 1 | 1 |
| 8hex | = | 8dec | = | 10oct | = | 1 | 0 | 0 | 0 |
| 9hex | = | 9dec | = | 11oct | = | 1 | 0 | 0 | 1 |
| Ahex | = | 10dec | = | 12oct | = | 1 | 0 | 1 | 0 |
| Bhex | = | 11dec | = | 13oct | = | 1 | 0 | 1 | 1 |
| Chex | = | 12dec | = | 14oct | = | 1 | 1 | 0 | 0 |
| Dhex | = | 13dec | = | 15oct | = | 1 | 1 | 0 | 1 |
| Ehex | = | 14dec | = | 16oct | = | 1 | 1 | 1 | 0 |
| Fhex | = | 15dec | = | 17oct | = | 1 | 1 | 1 | 1 |
Do czego będziemy dążyć w tym tutorialu, chcemy ten plik txt ze swoim imieniem zakodować na poziomie hexów, powiedzmy kluczem będzie słowo „abc” Z poprzedniego tutorala wiemy, że nasza maszyna kodująca słowo Piotrek kodowała by tak:
Nasz klucz „abc” przesuwa litery o „1 , 2 , 3” do przodu tak więc P +1 = 16 + 1= 17 = R i +2 = 9+2 =11 = k o +3 = 15+3 = 18 =s t +1 = 19+1 = 20 =w r +2 =17+2=19=t e +3 = 5+3 = 8 =h k +1 = 11+1 = 12 = l Ostatecznie Piotrek =>(abc)=> Rkswthl
I tak właśnie wyszło w programie z poprzedniego tutoriala:
Tekst taki jak „Rkswthl” może i jest trudny do rozkodowania ale nie niemożliwy poddając to odpowiednim algorytmom można tekst tem łatwo rozkodować. Gorzej jest jeśli nasz tekst jest bardzo duży, wtedy można dopasować rozkład liter i z łatwością odczytać tekst. Co się stanie jeśli zakodujemy hexy w takim tekście, już wam pokazuje. Przesuwamy hexy tak jak na górze przesuwaliśmy litery:
50 69 6f 74 72 65 6b 5 +1 = 6 0 + 2 =2 6 + 3 = 9 9 +1 = A 6 +2 = 8 f + 3 =2 (..) 50-69-6F-74-72-65-6B =>(abc) => 62-9A-82-86-A3-88-7D co po otwarciu pliku tekstowego daje w nim tekst: bš‚†Ł} Jak widzicie ciąg „bš‚†Ł}” wcale nie przypomina „Piotrek”
Program który sobie zrobimy nadaje się do kodowania i rozkodowywania plików *.txt ale może kodować również pliki *.jpg *.pdf, *.xls co tylko chcemy. Zrobimy sobie program i będziecie mogli zaraz zrozumieć o co w tym wszystkim chodzi. dla działu vb.net zrobię edytor hexó, więc warto i tam zajrzeć aby obejrzeć inny program. Zaczynamy standardowo od utworzenia nowego projektu. Teraz należy poukładać wszystkie elementy tak jak na obrazku:
Kiedy wszystkie elementy będą na swoim miejscu dodajemy OpenFileDialog i SaveFileDialog , oba elementy znajdują się w przyborniku po lewej stronie.
W tej części to będzie wszystko, formę wizualną mamy już gotową. Przechodzimy do kodu naszego programu. Najpierw inicjujemy dwie numeracje:
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
Public Enum SystemSzesnastkowy
n0 = 1
n1 = 2
n2 = 3
n3 = 4
n4 = 5
n5 = 6
n6 = 7
n7 = 8
n8 = 9
n9 = 10
nA = 11
nB = 12
nC = 13
nD = 14
nE = 15
nF = 16
End Enum
Pierwsza numeracja znana jest nam z poprzedniego tutoriala. Potrzebujemy jej aby na podstawie klucza rozpoznać wartość przesunięcia. Druga natomiast posłuży nam do szyfrowania. Teraz zainicjujemy sobie jeszcze zmienne:
Dim hexString As String 'jako bufor dla RichBoxów
Dim ListaBytow As New List(Of String) ' liste wszystkich bajtów zamienionych na hexy
Dim ListaBytowZakiRozk As New List(Of String) ' liste wszystkich bajtów zamienionych na hexy po zaszyfrowaniu
Wracamy do naszego Projektu i przyciskają dwukrotnie na przycisk „Otwórz” tworzymy do niego uchwyt. W uchwycie wpisujemy:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
hexString = "" ' Czyści nasz bufor
ProgressBar1.Maximum = 0 ' zeruje ProgressBar
If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
Using file As New IO.FileStream(OpenFileDialog1.FileName, IO.FileMode.Open)
Dim value As Integer = file.ReadByte()
Do Until value = -1 'pętla zamienia bajty na hexy
Dim hex As String
hex = Conversion.Hex(value)
If hex.Length < 2 Then
hex = "0" + hex
hexString += "-" & hex
ListaBytow.Add(hex)
Else
hexString += "-" & (hex) 'wypełnia bufor danymi
ListaBytow.Add(hex) 'dodaje hexy do listy
End If
value = file.ReadByte()
Loop
End Using
RichTextBox1.Text = hexString.Remove(0, 1) 'wizualizuje hexy w richbox1
ProgressBar1.Maximum = ListaBytow.Count()
End If
End Sub
Do przerobienia bajtów na hexy służy prosta funkcja „Coversion.Hex” która automatycznie robi to za nas. Pętla chyba prosta. Do zamiany bajtów na hexy może posłużyć również metoda:
Do Until value = -1
hexString += "-" (value.ToString("X2"))
(...)
Na koniec wczytuje wszystkie dane z bufora „hexString” do richBoxa ucinając pierwszy wyraz bo jest nim „-” (dodaje to lepszego efektu wizualnego) i ustawiam progressbar. Teraz zajmiemy się szyfrowanie. Wracamy do projektu i tworzymy uchwyt dla przycisku „Koduj”.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
hexString = "" 'czyści bufor
RichTextBox2.Clear() 'czyści richbox
Dim klucz As New List(Of Integer)
'pętla zamienia litery z textboxa1 na cyfry z numeracji i wypełnia tablice "klucz"
For Each letter As String In TextBox1.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
'wizualizuje sposób przesunięcia
TextBox2.Text = ""
For Each listaKlucza As Integer In klucz
TextBox2.Text += listaKlucza.ToString + ","
Next
'zeruje położenie w kluczu
Dim polozenieWKluczu As Integer = 0
'Pętla wstępnie kodująca
For Each elementglowny In ListaBytow 'dla każdego elementu z tabeli przechowującej bajty
'zerowanie bufora kodującego
Dim mojByte As String = ""
'Pętla wybierająca położenie w kluczu
For Each elements As String In elementglowny
If polozenieWKluczu > klucz.Count - 1 Then
mojByte += zaszyfruj(elements, klucz(0))
polozenieWKluczu = 1
Else
mojByte += zaszyfruj(elements, klucz(polozenieWKluczu))
polozenieWKluczu += 1
End If
Next
hexString += "-" + mojByte 'służy wypełnienie bufora wizualizującego dla richboxa2
ListaBytowZakiRozk.Add(mojByte) ' wypełnia tablice zagodowanymi hexami
ProgressBar1.Value += 1 'przesuwa progressbar
Next
RichTextBox2.Text = hexString.Remove(0, 1) 'wypelnia richbox2 danymi
ProgressBar1.Value = 0 'zeruje progressbar
End Sub
Tworzymy teraz funkcje szyfrującą. Będzie ona wyglądała trochę inaczej niż ta w poprzednim tutorialu. Jak sami zauważyliście w mojej numeracji dodałem przed cyfry i litery literę n. Ponieważ w numeracji nie da się numerować cyfr dodałem swego rodzaju wyznacznik który zdał egzamin dlatego nie kombinowałem dalej. Dodałem także dodatkowe „ifelse” do pętli ponieważ w systemie szesnastkowym mamy 16 cyfr a w systemie z literami mamy 24 chciałem pokazać wam, że jeśli nasz alfabet będzie miał więcej liter wtedy będziemy musieli odjąć 32:
jeśli przesunęli byśmy litere F o maksymalną liczbę czyli z mojego wyliczenia alfabetu jest to x-24 wtedy otrzymalibyśmy F-0, 0-1,1-2,2-3,3-4,4-5,5-6,6-7,7-8,8-9,9-10,A-11,B-12,C-13,D-14,E-15,F-16,0-17,1-18,2-19,3-20,4-21,5-22,6-23,7-24 Przesunięcie F o 24 daje 7 pierwsze przesunięcie da nam liczbę większą niż 16 a więc z poza zakresu: i + przesuniecie – 16 == 16+24-16 =24 w naszej numeracji nie istnieje pozycja 24 Drugie metoda za to: i + przesuniecie – 32 == 16+24-32 = 8 n8 w naszym wyliczeniu daje 7 Więc dla dużych liczb będziemy musieli odjąć 32 jeśli nasz alfabet będzie obszerny to dla jeszcze większych będziemy musieli odjąć 48
Cała funkcja wygląda tak:
Function zaszyfruj(ByVal litera As String, ByVal przesuniecie As Integer)
litera = "n" + litera 'dodaje wyznacznik do Enum
For Each i As Integer In [Enum].GetValues(GetType(SystemSzesnastkowy))
If litera = CType(i, SystemSzesnastkowy).ToString Then
If i + przesuniecie > 16 And i + przesuniecie <= 32 Then
Return Microsoft.VisualBasic.Right(CType(i + przesuniecie - 16, SystemSzesnastkowy).ToString, 1) '
ElseIf i + przesuniecie > 32 Then
Return Microsoft.VisualBasic.Right(CType(i + przesuniecie - 32, SystemSzesnastkowy).ToString, 1) '
Else
Return Microsoft.VisualBasic.Right(CType(i + przesuniecie, SystemSzesnastkowy).ToString, 1) '
End If
End If
Next
End Function
Można teraz spróbować sobie coś zaszyfrować. Ja zrobiłem sobie taki plik tekstowy:
Wczytam go teraz i zakoduje kodem „cba”. U mnie wszystko przebiegło pomyślnie:
Teraz uruchomimy sobie przycisk „Zapisz” tworzymy dla niego uchwyt i wpisujemy kod:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Try
If SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
Dim fs As New IO.FileStream(SaveFileDialog1.FileName, System.IO.FileMode.Create)
'dla każdego elementu z tablicy z zakodowanymi/ rozkodowanymi danymi
For Each elements In ListaBytowZakiRozk
Dim bytes As Byte = Convert.ToByte(elements, 16)
fs.WriteByte(bytes) 'zapisz bajty do wybranej lokalizacji i pliku
Next
End If
Catch
End Try
End Sub
Co dostaniemy po zapisaniu naszego pliku. Ja po zapisaniu zakodowanego pliku jako „plik_zakodowany.txt” i dostałem:
Sami przyznacie, że ciężko było by to rozkodować. Teraz zajmiemy się przyciskiem „Rozkoduj” z naszego Projektu. Kod do przycisku będzie Identyczny jak do kodowania, różnić się będzie tylko przesunięcie w funkcji do rozkodowania:
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
hexString = ""
RichTextBox2.Clear()
Dim klucz As New List(Of Integer)
For Each letter As String In TextBox1.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
TextBox2.Text += listaKlucza.ToString + ","
Next
Dim polozenieWKluczu As Integer = 0
For Each elementglowny In ListaBytow
Dim mojByte As String = ""
For Each elements As String In elementglowny
If polozenieWKluczu > klucz.Count - 1 Then
mojByte += rozszyfruj(elements, klucz(0))
polozenieWKluczu = 1
Else
mojByte += rozszyfruj(elements, klucz(polozenieWKluczu))
polozenieWKluczu += 1
End If
Next
hexString += "-" + mojByte
ListaBytowZakiRozk.Add(mojByte)
ProgressBar1.Value += 1
Next
RichTextBox2.Text = hexString.Remove(0, 1)
ProgressBar1.Value = 0
End Sub
Objaśnienie takie jak w metodzie kodującej. Funkcja rozkodująca wygląda tak:
Function rozszyfruj(ByVal litera As String, ByVal przesuniecie As Integer)
litera = "n" + litera
For Each i As Integer In [Enum].GetValues(GetType(SystemSzesnastkowy))
If litera = CType(i, SystemSzesnastkowy).ToString Then
If i - przesuniecie <= 0 And i - przesuniecie > -16 Then
Return Microsoft.VisualBasic.Right(CType(i - przesuniecie + 16, SystemSzesnastkowy).ToString, 1)
ElseIf i - przesuniecie <= -16 Then
Return Microsoft.VisualBasic.Right(CType(i - przesuniecie + 32, SystemSzesnastkowy).ToString, 1)
Else
Return Microsoft.VisualBasic.Right(CType(i - przesuniecie, SystemSzesnastkowy).ToString, 1)
End If
End If
Next
End Function
Otwieramy teraz wcześniej zakodowany plik i wciskamy „Rozkoduj”
Zapisujemy go i dostajemy nasze hasło:
Uważajcie, używajcie tylko liter z numeracji, jeśli chcecie aby w kluczu były cyfry najlepiej też dla każdej cyfry użyć wyznacznika albo w pętli użyć metody isNumeric():
Dim klucz As New List(Of Integer)
For Each letter As String In TextBox1.Text
If IsNumeric(letter) Then
klucz.Add(letter)
Else
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
End If
Next
Oczywiście trzeba to jakoś mądrze wykonać. Wszelkiego rodzaju krytykę proszę pisać w komentarzach. Jeśli coś jest nie jasne to proszę o kontakt albo komentarza.
Cały projekt można pobrać: Szyfrowanie_hexow
Sam plik *.exe programu do sprawdzenia: Szyfrowanie_hexow_exe

