Jest to rodzaj szyfru strumieniowego wykorzystywanego przez firmę Microsoft we wczesnych wersjach jego produktów takich jak Word, Excel.
Word 2.0 – 95, Excel 4.0 – 95 Te wersje aplikacji Microsoft Office wykorzystywały słaby algorytm szyfrowania oparty na operacji XOR. Nawet w tamtych czasach siła tego algorytmu polegała raczej na zaciemnianiu niż szyfrowaniu. Wszystkie hasła do wszystkich wersji Worda i Excela do Office 95 włącznie można było odzyskać natychmiast; ataki siłowe nie były wymagane.
Działanie szyfru opiera się na działaniu logiki matematycznej XOR czyli alternatywie rozłącznej. W logice matematycznej alternatywę rozłączną zapisuje się jako
Alternatywa rozłączna dla ( p q) jest zdaniem prawdziwym, gdy co najmniej jedno z jej zdań składowych p, q jest prawdziwe a drugie nie. Operację oznaczamy znakiem
Tablica prawdy dla alternatywy rozłącznej:
p
q
0
0
0
0
1
1
1
0
1
1
1
0
Wykorzystując ten rodzaj szyfru, będziemy operować na komputerowych bitach, bit (binary digit, czyli cyfra dwójkowa) to najmniejsza jednostka informacji używana w odniesieniu do sprzętu komputerowego. Bit może posiadać dwa stany 1 albo 0, każdy znak, obraz, element wyświetlony na ekranie komputera ma swoją interpretację w systemie dwójkowym. Sprawdźmy poniższy kod:
Module Program
Dim wiadomosc As String = "szyfr"
Dim ASCII_numery As String
Dim Hex_n As String
Dim Dec_n As String
Dim Bin_n As String
Sub Main()
For i As Int32 = 0 To wiadomosc.Length - 1
Dim k As Integer = Asc(wiadomosc(i)) ' Convert to ASCII integer (Dec).
ASCII_numery += k.ToString + ","
Hex_n += Conversion.Hex(k) + "," ' Convert to HEX integer.
Dim oReturn As New System.Text.StringBuilder
'Convert to Bin
For Each Character As Byte In System.Text.ASCIIEncoding.ASCII.GetBytes(wiadomosc(i))
oReturn.Append(Convert.ToString(Character, 2).PadLeft(8, "0"))
oReturn.Append(",")
Next
Bin_n += oReturn.ToString
Next
Console.WriteLine(ASCII_numery.ToString) '115,122,121,102,114
Console.WriteLine(Hex_n.ToString) '73,7A,79,66,72
Console.WriteLine(Bin_n.ToString) '01110011,01111010,01111001,01100110,01110010
Console.ReadLine()
End Sub
End Module
Uruchamiając powyższy kod wyświetlimy interpretacje słowa „szyfr” w systemie dwójkowym.
Jeśli chcielibyśmy zaszyfrować nasze słowo i do zaszyfrowania użyjemy pojedynczej litery „c” której dwu-bitowa interpretacja wynosi 01100011 nasz szyfr będzie wyglądał następująco:
Problem który na pierwszy rzut oka każdy zauważy to, że jeśli szyfrujemy literę za pomocą siebie samej to efekt będzie zawsze ten sam czyli 00000000, to bardzo ważna informacja która ułatwia atakującemu złamanie szyfru.
Imports System.Text
Module Program
Dim wiadomosc As String = "atak 20:00"
Dim klucz As String = "cba"
Dim kluczSzyfrujacy As String
Dim Bin_n As String
Dim Bin_n_key As String
Dim szyfrogram As String
Dim szyfrogramBit As String
Dim separator As String
Sub Main()
For i As Integer = 0 To wiadomosc.Length - 1
Dim oReturn As New System.Text.StringBuilder
Dim oReturnKey As New System.Text.StringBuilder
Dim oReturnS As New System.Text.StringBuilder
Dim znakSzyfrogramu As Char = getBites(wiadomosc(i), i)
zamienNaBity(oReturn, wiadomosc(i))
zamienNaBity(oReturnKey, klucz(i Mod klucz.Length))
zamienNaBity(oReturnS, znakSzyfrogramu)
separator += "---------"
kluczSzyfrujacy += klucz(i Mod klucz.Length)
szyfrogram += znakSzyfrogramu
Bin_n += oReturn.ToString
Bin_n_key += oReturnKey.ToString
szyfrogramBit += oReturnS.ToString
Next
Console.WriteLine(Bin_n)
Console.WriteLine(Bin_n_key)
Console.WriteLine(separator)
Console.WriteLine(szyfrogramBit)
Console.WriteLine()
Console.WriteLine(wiadomosc + " --> " + kluczSzyfrujacy + " === " + szyfrogram)
Console.ReadLine()
End Sub
Private Sub zamienNaBity(oReturnS As StringBuilder, znakSzyfrogramu As Char)
For Each Character As Byte In System.Text.ASCIIEncoding.ASCII.GetBytes(znakSzyfrogramu)
oReturnS.Append(Convert.ToString(Character, 2).PadLeft(8, "0"))
oReturnS.Append(",")
Next
End Sub
Private Function getBites(znak As Char, i As Integer) As Char
Dim znakKlucza As Byte() = Text.Encoding.ASCII.GetBytes(klucz(i Mod klucz.Length))
Dim bajtZnaku As Byte() = Text.Encoding.ASCII.GetBytes(znak)
Dim tablicaBitowaZnakuKlucza As New BitArray({znakKlucza(0)})
Dim tablicaBitowaZnaku As New BitArray({bajtZnaku(0)})
Dim szyfrogram As New BitArray(8)
For a As Integer = 0 To 7<br /> szyfrogram(a) = tablicaBitowaZnakuKlucza(a) Xor tablicaBitowaZnaku(a)<br /> Next
Dim bajtSzyfrogramu As Byte() = BitArrayToByteArray(szyfrogram)
Dim vOut As Char = Convert.ToChar(bajtSzyfrogramu(0))
Return vOut
End Function
Private Function BitArrayToByteArray(bits As BitArray) As Byte()
Dim ret As Byte() = New Byte((bits.Length - 1) / 8 + 1 - 1) {}
bits.CopyTo(ret, 0)
Return ret
End Function
End Module
Efekt wykonania powyższego kodu, szyfrującego tekst „atak 20:00” przy pomocy klucza „cba” :
Jak widzimy z powyższego obrazka, nasz szyfrogram wygląda bardzo przyzwoicie a deszyfrowanie odbywa się poprzez użycie klucza i tej samej metody getBites() czyli odwrócenie szyfrowania:
Imports System.Text
Module Program
Dim wiadomosc As String = "atak 20:00"
Dim klucz As String = "cba"
Dim kluczSzyfrujacy As String
Dim Bin_n As String
Dim Bin_n_key As String
Dim szyfrogram As String
Dim szyfrogramBit As String
Dim separator As String
Dim ujawnionyTekst As String
Sub Main()
For i As Integer = 0 To wiadomosc.Length - 1
Dim oReturn As New System.Text.StringBuilder
Dim oReturnKey As New System.Text.StringBuilder
Dim oReturnS As New System.Text.StringBuilder
Dim znakSzyfrogramu As Char = getBites(wiadomosc(i), i)
zamienNaBity(oReturn, wiadomosc(i))
zamienNaBity(oReturnKey, klucz(i Mod klucz.Length))
zamienNaBity(oReturnS, znakSzyfrogramu)
separator += "---------"
kluczSzyfrujacy += klucz(i Mod klucz.Length)
szyfrogram += znakSzyfrogramu
Bin_n += oReturn.ToString
Bin_n_key += oReturnKey.ToString
szyfrogramBit += oReturnS.ToString
Next
Console.WriteLine(Bin_n)
Console.WriteLine(Bin_n_key)
Console.WriteLine(separator)
Console.WriteLine(szyfrogramBit)
Console.WriteLine()
Console.WriteLine(wiadomosc + " --> " + kluczSzyfrujacy + " === " + szyfrogram)
Console.ReadLine()
For i As Integer = 0 To szyfrogram.Length - 1
Dim znakJawny As Char = getBites(szyfrogram(i), i)
ujawnionyTekst += znakJawny
Next
Console.WriteLine(ujawnionyTekst)
Console.ReadLine()
End Sub
Private Sub zamienNaBity(oReturnS As StringBuilder, znakSzyfrogramu As Char)
For Each Character As Byte In System.Text.ASCIIEncoding.ASCII.GetBytes(znakSzyfrogramu)
oReturnS.Append(Convert.ToString(Character, 2).PadLeft(8, "0"))
oReturnS.Append(",")
Next
End Sub
Private Function getBites(znak As Char, i As Integer) As Char
Dim znakKlucza As Byte() = Text.Encoding.ASCII.GetBytes(klucz(i Mod klucz.Length))
Dim bajtZnaku As Byte() = Text.Encoding.ASCII.GetBytes(znak)
Dim tablicaBitowaZnakuKlucza As New BitArray({znakKlucza(0)})
Dim tablicaBitowaZnaku As New BitArray({bajtZnaku(0)})
Dim szyfrogram As New BitArray(8)
For a As Integer = 0 To 7<br /> szyfrogram(a) = tablicaBitowaZnakuKlucza(a) Xor tablicaBitowaZnaku(a)<br /> Next
Dim bajtSzyfrogramu As Byte() = BitArrayToByteArray(szyfrogram)
Dim vOut As Char = Convert.ToChar(bajtSzyfrogramu(0))
Return vOut
End Function
Private Function BitArrayToByteArray(bits As BitArray) As Byte()
Dim ret As Byte() = New Byte((bits.Length - 1) / 8 + 1 - 1) {}
bits.CopyTo(ret, 0)
Return ret
End Function
End Module
Operator XOR jest niezwykle powszechny jako składnik bardziej złożonych szyfrów. Samo w sobie, używając stale powtarzającego się klucza, szyfr XOR można w prosty sposób złamać za pomocą analizy częstotliwości. Jeśli można odgadnąć treść wiadomości lub poznać ją w inny sposób, można ujawnić klucz. Jego podstawową zaletą jest to, że jest łatwy do wdrożenia, a operacja XOR jest tania obliczeniowo. Prosty, powtarzający się XOR jest zatem czasami używany do ukrywania informacji w przypadkach, gdy nie jest wymagane żadne szczególne zabezpieczenie. Szyfr XOR jest często używany w złośliwym oprogramowaniu komputerowym, aby utrudnić inżynierię wsteczną.
Jeśli klucz jest losowy i ma co najmniej taką samą długość jak wiadomość, szyfr XOR jest znacznie bezpieczniejszy niż w przypadku powtórzenia klucza w wiadomości. Gdy strumień klucza jest generowany przez generator liczb pseudolosowych, wynikiem jest szyfr strumieniowy. W przypadku klucza, który jest naprawdę losowy, wynikiem jest jednorazowa podkładka, której teoretycznie nie można złamać.
W każdym z tych szyfrów operator XOR jest podatny na atak znanego tekstu jawnego. Jest również możliwe przerzucanie dowolnych bitów w odszyfrowanym tekście jawnym poprzez manipulowanie tekstem zaszyfrowanym. Nazywa się to plastycznością i jest to cecha bardzo niepożądana w krypto systemie, nie odnosi się do zdolności atakującego do odczytania zaszyfrowanej wiadomości a do możliwości jej modyfikacji.
Sprawdźmy jak będzie wyglądało szyfrowanie pikseli obrazka, do celów testowych użyjemy naszego kotka:
Nasz obrazek ma wymiar 256×194, każdy piksel jest reprezentacją modelu przestrzeni barw RGB (R – red (czerwonej), G – green (zielonej) i B – blue (niebieskiej)) każdy kolor przyjmuje wartość od 0 do 256 czyli jego reprezentacja to jeden bajt. Czyli w naszym wypadku mamy do zaszyfrowania 256 * 194 *3 = 148 992 bajty. To daje nam bardzo dużą szansę na spojrzenie z góry i wychwycenie powtarzających się schematów które mogą ułatwić odszyfrowanie obrazka bądź tekstu i uwypuklą wady szyfru XOR. Do zaszyfrowania naszego obrazka użyjemy klucza generowanego pseudo losowo podczas każdej operacji XOR. Efektem będzie zaszyfrowany obrazek i klucz.
Imports System.Windows.Forms
Imports System.Drawing
Imports System.IO
Module Module1
Dim klucz As New List(Of Byte)
Dim losowy As New Random
Dim pozycjaKlucza As Integer = 0
Sub Main()
'Otwiera dialog z użytkownikiem
Console.WriteLine("Co chesz zrobić? Wpisz cyfrę zadania." _
+ vbNewLine + "1.Zaszyfruj obrazek." _
+ vbNewLine + "2.Odszyfruj obrazek.")
Dim wyborUzytkownika As String
Do
wyborUzytkownika = Console.ReadLine()
If wyborUzytkownika = "1" Or wyborUzytkownika = "2" Then
Exit Do
Else
Console.WriteLine("Możesz wybrać tylko cyfrę 1 lub 2.")
End If
Loop
'zrealizuj wybraną opcję
If wyborUzytkownika = 1 Then
szyfrujObrazek()
Else
odszyfrujObrazek()
End If
Console.ReadLine()
End Sub
Private Sub szyfrujObrazek()
Dim dialog As OpenFileDialog = showFileDialog()
If dialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Dim bmp As New Bitmap(dialog.FileName)
wyswietlObrazek(bmp)
Dim R As Byte, G As Byte, B As Byte
Dim xmax As Integer = bmp.Width - 1
Dim ymax As Integer = bmp.Height - 1
For y = 0 To ymax
For x = 0 To xmax
With bmp.GetPixel(x, y)
R = zamienByte(.R, True)
G = zamienByte(.G, True)
B = zamienByte(.B, True)
End With
bmp.SetPixel(x, y, Color.FromArgb(R, G, B))
Next x
Next y
wyswietlObrazek(bmp)
zapiszObrazek(bmp)
zapiszKlucz(klucz.ToArray)
Console.WriteLine("Operacja zakończona pomyślnie, plik został zaszyfrowany.")
End If
End Sub
Private Sub odszyfrujObrazek()
Dim open_dialog As OpenFileDialog = showFileDialog()
If open_dialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Dim bmp As New Bitmap(open_dialog.FileName)
wyswietlObrazek(bmp)
otworzKlucz()
Dim R As Byte, G As Byte, B As Byte
Dim xmax As Integer = bmp.Width - 1
Dim ymax As Integer = bmp.Height - 1
For y = 0 To ymax
For x = 0 To xmax
With bmp.GetPixel(x, y)
R = zamienByte(.R, False)
pozycjaKlucza += 1
G = zamienByte(.G, False)
pozycjaKlucza += 1
B = zamienByte(.B, False)
pozycjaKlucza += 1
End With
bmp.SetPixel(x, y, Color.FromArgb(R, G, B))
Next x
Next y
wyswietlObrazek(bmp)
zapiszObrazek(bmp)
Console.WriteLine("Operacja zakończona pomyślnie, plik został odszyfrowany.")
End If
End Sub
Private Function zamienByte(znak As Byte, szyfrowanie As Boolean) As Byte
Dim znakKlucza As Byte
If szyfrowanie Then
znakKlucza = BitConverter.GetBytes(losowy.Next(0, 256))(0)
klucz.Add(znakKlucza)
Else
znakKlucza = klucz(pozycjaKlucza)
End If
Dim tablicaBitowaZnakuKlucza As New BitArray({znakKlucza})
Dim tablicaBitowaZnaku As New BitArray({znak})
Dim szyfrogram As New BitArray(8)
'zamienNaBity(znak)
'zamienNaBity(znakKlucza(0))
For a As Integer = 0 To 7
szyfrogram(a) = tablicaBitowaZnakuKlucza(a) Xor tablicaBitowaZnaku(a)
Next
'Console.WriteLine(vbTab + "---------")
Dim bajtSzyfrogramu As Byte() = BitArrayToByteArray(szyfrogram)
'zamienNaBity(bajtSzyfrogramu(0))
'Console.WriteLine("")
Dim vOut As Char = Convert.ToChar(bajtSzyfrogramu(0))
Return bajtSzyfrogramu(0)
End Function
Private Function BitArrayToByteArray(bits As BitArray) As Byte()
Dim ret As Byte() = New Byte((bits.Length - 1) / 8 + 1 - 1) {}
bits.CopyTo(ret, 0)
Return ret
End Function
Private Sub zamienNaBity(znak As Byte)
Dim oReturn As New System.Text.StringBuilder
oReturn.Append(znak.ToString + vbTab + "=")
oReturn.Append(Convert.ToString(znak, 2).PadLeft(8, "0"))
oReturn.Append("- " + Chr(znak))
Console.WriteLine(oReturn)
End Sub
Private Sub zapiszObrazek(bmp As Bitmap)
Dim dialogZapisu As New SaveFileDialog()
dialogZapisu.Title = "Zapisz plik bmp"
dialogZapisu.Filter = "BMP Files | *.bmp"
dialogZapisu.DefaultExt = "bmp"
dialogZapisu.ShowDialog()
If dialogZapisu.FileName <> "" Then
bmp.Save(dialogZapisu.FileName, Imaging.ImageFormat.Bmp)
End If
End Sub
Private Sub zapiszKlucz(klucz As Byte())
Dim dialogZapisu As New SaveFileDialog()
dialogZapisu.Title = "Zapisz plik klucza"
dialogZapisu.Filter = "Key Files | *.key"
dialogZapisu.DefaultExt = "key"
dialogZapisu.ShowDialog()
If dialogZapisu.FileName <> "" Then
IO.File.WriteAllBytes(dialogZapisu.FileName, klucz)
End If
End Sub
Private Function showFileDialog() As OpenFileDialog
Dim dialogWyboru As New OpenFileDialog()
dialogWyboru.InitialDirectory = "c:\"
dialogWyboru.Filter = "Image Files (*.bmp)|*.bmp"
Return dialogWyboru
End Function
Private Sub otworzKlucz()
Dim open_dialog As New OpenFileDialog()
open_dialog.InitialDirectory = "c:\"
open_dialog.Filter = "Key Files (*.key)|*.key"
If open_dialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
klucz = File.ReadAllBytes(open_dialog.FileName).ToList
End If
End Sub
Private Sub wyswietlObrazek(obrazek As Bitmap)
Dim formaGrafiki As Form = New Form()
formaGrafiki.Text = "Zanknij okno aby kontynuować."
formaGrafiki.BackgroundImage = obrazek
formaGrafiki.BackgroundImageLayout = ImageLayout.Center
formaGrafiki.ShowDialog()
End Sub
End Module
Powyższy kod służy do szyfrowania i deszyfrowania obrazka przy pomocy klucza pseudo losowego o długości ilości bajtów kolorów w obrazku. Zajmiemy się teraz czymś ciekawym, porównamy inne operacje logiczne. Jak wiemy, w matematyce występują dwie podobne operacje OR i AND a efekt ich użycia wraz z kluczem pseudo losowym jest tak ciekawy, że nie mogę ominąć tej kwestii i muszę wam pokazać ten efekt
Aby dokonać tego typu zmian należy zaktualizować linię 121 naszego kodu:
Dla operatora logicznego „AND”
For a As Integer = 0 To 7
szyfrogram(a) = tablicaBitowaZnakuKlucza(a) And tablicaBitowaZnaku(a)
Next
Dla operatora logicznego „OR”
For a As Integer = 0 To 7
szyfrogram(a) = tablicaBitowaZnakuKlucza(a) Or tablicaBitowaZnaku(a)
Next
Wiemy jak używać naszego szyfru XOR z kluczem pseudo losowym ale jego zastosowanie nie wydaję się wygodne, klucz wielkości szyfrogramu jest niewygodny a jego utrata będzie wiązała się z utratą pliku bazowego. Łatwiejszym sposobem jest utworzenie hasła i za jego pomocą szyfrowanie pliku. Zobaczmy jak to się sprawdzi w praktyce. Naszym hasłem będzie: VisualMonsters.cba.pl Efekt takiego szyfru nie jest zbyt imponujący:
Kod który posłużył do zaszyfrowania naszego pliku:
Imports System.Windows.Forms
Imports System.Drawing
Module Module1
Dim klucz As String = "VisualMonsters.cba.pl"
Sub Main()
'Otwiera dialog z użytkownikiem
Console.WriteLine("Co chesz zrobić? Wpisz cyfrę zadania." _
+ vbNewLine + "1.Zaszyfruj obrazek." _
+ vbNewLine + "2.Odszyfruj obrazek.")
Dim wyborUzytkownika As String
Do
wyborUzytkownika = Console.ReadLine()
If wyborUzytkownika = "1" Or wyborUzytkownika = "2" Then
Exit Do
Else
Console.WriteLine("Możesz wybrać tylko cyfrę 1 lub 2.")
End If
Loop
'zrealizuj wybraną opcję
If wyborUzytkownika = 1 Then
szyfrujObrazek()
Else
szyfrujObrazek()
End If
Console.ReadLine()
End Sub
Private Sub szyfrujObrazek()
Dim dialog As OpenFileDialog = showFileDialog()
If dialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Dim bmp As New Bitmap(dialog.FileName)
wyswietlObrazek(bmp)
Dim R As Byte, G As Byte, B As Byte
Dim xmax As Integer = bmp.Width - 1
Dim ymax As Integer = bmp.Height - 1
Dim i As Integer = 0
For y = 0 To ymax
For x = 0 To xmax
With bmp.GetPixel(x, y)
R = zamienByte(.R, i)
i += 1
G = zamienByte(.G, i)
i += 1
B = zamienByte(.B, i)
i += 1
End With
bmp.SetPixel(x, y, Color.FromArgb(R, G, B))
Next x
Next y
wyswietlObrazek(bmp)
zapiszObrazek(bmp)
Console.WriteLine("Operacja zakończona pomyślnie.")
End If
End Sub
Private Function zamienByte(znak As Byte, i As Integer) As Byte
Dim znakKlucza As Byte
znakKlucza = BitConverter.GetBytes(klucz(i Mod klucz.Length))(0)
Dim tablicaBitowaZnakuKlucza As New BitArray({znakKlucza})
Dim tablicaBitowaZnaku As New BitArray({znak})
Dim szyfrogram As New BitArray(8)
For a As Integer = 0 To 7
szyfrogram(a) = tablicaBitowaZnakuKlucza(a) Xor tablicaBitowaZnaku(a)
Next
Dim bajtSzyfrogramu As Byte() = BitArrayToByteArray(szyfrogram)
Dim vOut As Char = Convert.ToChar(bajtSzyfrogramu(0))
Return bajtSzyfrogramu(0)
End Function
Private Function BitArrayToByteArray(bits As BitArray) As Byte()
Dim ret As Byte() = New Byte((bits.Length - 1) / 8 + 1 - 1) {}
bits.CopyTo(ret, 0)
Return ret
End Function
Private Sub zapiszObrazek(bmp As Bitmap)
Dim dialogZapisu As New SaveFileDialog()
dialogZapisu.Title = "Zapisz plik bmp"
dialogZapisu.Filter = "BMP Files | *.bmp"
dialogZapisu.DefaultExt = "bmp"
dialogZapisu.ShowDialog()
If dialogZapisu.FileName <> "" Then
bmp.Save(dialogZapisu.FileName, Imaging.ImageFormat.Bmp)
End If
End Sub
Private Function showFileDialog() As OpenFileDialog
Dim dialogWyboru As New OpenFileDialog()
dialogWyboru.InitialDirectory = "c:\"
dialogWyboru.Filter = "Image Files (*.bmp)|*.bmp"
Return dialogWyboru
End Function
Private Sub wyswietlObrazek(obrazek As Bitmap)
Dim formaGrafiki As Form = New Form()
formaGrafiki.Text = "Zanknij okno aby kontynuować."
formaGrafiki.BackgroundImage = obrazek
formaGrafiki.BackgroundImageLayout = ImageLayout.Center
formaGrafiki.ShowDialog()
End Sub
End Module
Bardzo dobrze widać na naszym obrazku sekwencje klucza:
Prosty trik zapewni nam względną losowość, zmiana linii 71 na:
If Not i = 0 Then
Dim znakInt As Integer = Convert.ToByte(klucz(i Mod klucz.Length))
znakInt = znakInt * i
znakKlucza = BitConverter.GetBytes(znakInt Mod 256)(0)
Else
znakKlucza = BitConverter.GetBytes(klucz(i Mod klucz.Length))(0)
End If
spowoduje przemnożenie klucza przez pozycję piksela. Nasz obrazek zniknie w mgnieniu oka:
Nadal wyczuwalna jest nutka sekwencji ale prosty trik zapewnił nam akceptowalny poziom zabezpieczenia. Pełen kod:
Imports System.Windows.Forms
Imports System.Drawing
Module Module1
Dim klucz As String = "VisualMonsters.cba.pl"
Sub Main()
'Otwiera dialog z użytkownikiem
Console.WriteLine("Co chesz zrobić? Wpisz cyfrę zadania." _
+ vbNewLine + "1.Zaszyfruj obrazek." _
+ vbNewLine + "2.Odszyfruj obrazek.")
Dim wyborUzytkownika As String
Do
wyborUzytkownika = Console.ReadLine()
If wyborUzytkownika = "1" Or wyborUzytkownika = "2" Then
Exit Do
Else
Console.WriteLine("Możesz wybrać tylko cyfrę 1 lub 2.")
End If
Loop
'zrealizuj wybraną opcję
If wyborUzytkownika = 1 Then
szyfrujObrazek()
Else
szyfrujObrazek()
End If
Console.ReadLine()
End Sub
Private Sub szyfrujObrazek()
Dim dialog As OpenFileDialog = showFileDialog()
If dialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Dim bmp As New Bitmap(dialog.FileName)
wyswietlObrazek(bmp)
Dim R As Byte, G As Byte, B As Byte
Dim xmax As Integer = bmp.Width - 1
Dim ymax As Integer = bmp.Height - 1
Dim i As Integer = 0
For y = 0 To ymax
For x = 0 To xmax
With bmp.GetPixel(x, y)
R = zamienByte(.R, i)
i += 1
G = zamienByte(.G, i)
i += 1
B = zamienByte(.B, i)
i += 1
End With
bmp.SetPixel(x, y, Color.FromArgb(R, G, B))
Next x
Next y
wyswietlObrazek(bmp)
zapiszObrazek(bmp)
Console.WriteLine("Operacja zakończona pomyślnie.")
End If
End Sub
Private Function zamienByte(znak As Byte, i As Integer) As Byte
Dim znakKlucza As Byte
If Not i = 0 Then
Dim znakInt As Integer = Convert.ToByte(klucz(i Mod klucz.Length))
znakInt = znakInt * i
znakKlucza = BitConverter.GetBytes(znakInt Mod 256)(0)
Else
znakKlucza = BitConverter.GetBytes(klucz(i Mod klucz.Length))(0)
End If
Dim tablicaBitowaZnakuKlucza As New BitArray({znakKlucza})
Dim tablicaBitowaZnaku As New BitArray({znak})
Dim szyfrogram As New BitArray(8)
For a As Integer = 0 To 7
szyfrogram(a) = tablicaBitowaZnakuKlucza(a) Xor tablicaBitowaZnaku(a)
Next
Dim bajtSzyfrogramu As Byte() = BitArrayToByteArray(szyfrogram)
Dim vOut As Char = Convert.ToChar(bajtSzyfrogramu(0))
Return bajtSzyfrogramu(0)
End Function
Private Function BitArrayToByteArray(bits As BitArray) As Byte()
Dim ret As Byte() = New Byte((bits.Length - 1) / 8 + 1 - 1) {}
bits.CopyTo(ret, 0)
Return ret
End Function
Private Sub zapiszObrazek(bmp As Bitmap)
Dim dialogZapisu As New SaveFileDialog()
dialogZapisu.Title = "Zapisz plik bmp"
dialogZapisu.Filter = "BMP Files | *.bmp"
dialogZapisu.DefaultExt = "bmp"
dialogZapisu.ShowDialog()
If dialogZapisu.FileName <> "" Then
bmp.Save(dialogZapisu.FileName, Imaging.ImageFormat.Bmp)
End If
End Sub
Private Function showFileDialog() As OpenFileDialog
Dim dialogWyboru As New OpenFileDialog()
dialogWyboru.InitialDirectory = "c:\"
dialogWyboru.Filter = "Image Files (*.bmp)|*.bmp"
Return dialogWyboru
End Function
Private Sub wyswietlObrazek(obrazek As Bitmap)
Dim formaGrafiki As Form = New Form()
formaGrafiki.Text = "Zanknij okno aby kontynuować."
formaGrafiki.BackgroundImage = obrazek
formaGrafiki.BackgroundImageLayout = ImageLayout.Center
formaGrafiki.ShowDialog()
End Sub
End Module