Szyfrowanie Hexów

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: szyfrowaniehexow3   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: szyfrowaniehexow Kiedy wszystkie elementy będą na swoim miejscu dodajemy OpenFileDialog i SaveFileDialog , oba elementy znajdują się w przyborniku po lewej stronie. szyfrowaniehexow2 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: szyfrowaniehexow4 Wczytam go teraz i zakoduje kodem „cba”. U mnie wszystko przebiegło pomyślnie: szyfrowaniehexow5 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: szyfrowaniehexow6 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” szyfrowaniehexow7 Zapisujemy go i dostajemy nasze hasło: szyfrowaniehexow8   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

Permalink do tego artykułu: https://visualmonsters.cba.pl/szyfrowanie-hexow/

Dodaj komentarz

Twój adres email nie będzie publikowany.