Cryptopals zestaw 1 ćwiczenie 1

przez | 20 stycznia 2020

W tym wpisie omówię pierwsze zadanie, a ponieważ jest bardzo proste to opiszę również strukturę projektu który został stworzony na potrzeby rozwiązywania kolejnych zadań.

Wszystkie rozwiązania są napisane w języku Python (wersja 3.7) przy użyciu Eclipse z wtyczką PyDev jako IDE. Struktura projektu:

  • src – katalog w którym znajduje się kod źródłowy projektu.
    • common – katalog w którym znajduje się kod źródłowy używany częściej niż w jednym zdaniu .
    • set1…n – katalogi w których znajdowały się będą rozwiązania dla kolejnych zestawów ćwiczeń.
    • cryptomain.py – plik w którym znajduje się funkcja main naszego projektu.
  • testfiles – katalog w którym znajdują się pliki testowe do sprawdzenia poprawności działania rozwiązań.

Oczywiście wraz z postępem prac projekt będzie ewoluował i część kodu będzie przepisywana i wędrowała do katalogu common. Cały projekt dostępny jest https://gitlab.com/akoltys/cryptopals .

Zestaw 1. Wyzwanie 1.

Pierwsze zadanie bardziej na rozgrzewkę o ile ktoś miał wcześniej do czynienia z base64 i nie boi się wartości heksadecymalnych. Na wejściu mamy podaną wartość:

49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d

A na wyjściu powinniśmy otrzymać:

SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t

Naszym zadaniem jest zakodowanie podanego ciągu binarnego do base64. Dla tych którzy nie wiedzą co to base64 (a zapewniam, że każdy go używa choć nie koniecznie świadomie) polecam poczytać na Wikipedii (https://pl.wikipedia.org/wiki/Base64) a tym, którzy chcą zgłębić temat polecam również https://tools.ietf.org/html/rfc4648.

Python ma w swoich standardowych bibliotekach moduł do obsługi base64 który pozwala na kodowanie i dekodowanie ciągów znaków. W tym zadaniu chcemy zakodować ciąg znaków i do tego użyjemy funkcji b64encode. Funkcja jako argument przyjmuje tablicę bajtów, dlatego pierwsze co należy zrobić to zamienić wartość wejściową na bajty, czyli pierwsze dwa znaki powinny zamienić się w bajt o wartości 0x49, dwa kolejne 0x27 potem 0x6d itd.

W katalogu src/common stworzyłem plik utils.py w którym dodałem dwie funkcje:

def bytes_to_base64(input_bytes):
return base64.b64encode(input_bytes)

def hex_string_to_base64(input_string):
return bytes_to_base64(bytes.fromhex(input_string))

Funkcja hex_string_to_base64 jako argument przyjmuje ciąg znaków ascii, konwertuje go na obiekt typu bytes przy pomocy metody bytes.fromhex() (https://docs.python.org/3/library/stdtypes.html#bytes.fromhex) i przekazuje to jako argument do funkcji bytes_to_base64, która z kolei przekazuje swój argument do funkcji z biblioteki standardowej base64.b64encode() (https://docs.python.org/3/library/base64.html#base64.b64encode).

Kod z moim rozwiązaniem pierwszego problemu:

def s1challenge1():
input_string = „49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d”
expected_output = b’SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t’
output_string = hex_string_to_base64(input_string)
print(output_string)
print(expected_output)

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *