W tym poście chciałbym opisać rozwiązania zadania Fixed XOR z Cryptopals.
Zadanie polega na wynik z poprzedniego zadania zastosować XOR:
- 1c0111001f010100061a024b53535009181c
- XOR
- 686974207468652062756c6c277320657965
- Wynik:
- 746865206b696420646f6e277420706c6179
Poprawność zadania można zweryfikować przez wprowadzenie danych do narzędzia online:
Zacznę od programu w Pythonie.
Python:
Najprościej wprowadzić dane jako ciągi liczb w postaci HEX, co wygląda mniej więcej tak:
- a = 0x1c0111001f010100061a024b53535009181c
- b = 0x686974207468652062756c6c277320657965
- print(hex(a ^ b))
W przypadku gdy dane wejściowe są wprowadzane jako ciągi znaków, to należy zastosować konwersję:
- a_str = "1c0111001f010100061a024b53535009181c"
- b_str = "686974207468652062756c6c277320657965"
- a = int(a_str, 16)
- b = int(b_str, 16)
- result = a ^ b
- print(hex(result)[2:])
C:
Język C nie pozwala na przechowywanie tak dużych danych w postaci jednej zmiennej. Więc należy zastosować tablicę i przechodzić XOR po każdym bajcie danych. Dokładnie to samo robi Python, tylko użytkownik załatwia te operacje jedną instrukcją. Tutaj trzeba się nieco więcej opisać.
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- int main() {
- unsigned char a[] = {
- 0x1c, 0x01, 0x11, 0x00, 0x1f, 0x01, 0x01, 0x00,
- 0x06, 0x1a, 0x02, 0x4b, 0x53, 0x53, 0x50, 0x09,
- 0x18, 0x1c
- };
- unsigned char b[] = {
- 0x68, 0x69, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20,
- 0x62, 0x75, 0x6c, 0x6c, 0x27, 0x73, 0x20, 0x65,
- 0x79, 0x65
- };
- size_t len = sizeof(a);
- unsigned char result[len];
- for (size_t i = 0; i < len; ++i) {
- result[i] = a[i] ^ b[i];
- }
- printf("0x");
- for (size_t i = 0; i < len; ++i) {
- printf("%02x", result[i]);
- }
- printf("\n");
- return 0;
- }
GO:
Poniżej jeszcze rozwiązania w języku GO:
- package main
- import "fmt"
- func main() {
- a := []byte{
- 0x1c, 0x01, 0x11, 0x00, 0x1f, 0x01, 0x01, 0x00,
- 0x06, 0x1a, 0x02, 0x4b, 0x53, 0x53, 0x50, 0x09,
- 0x18, 0x1c,
- }
- b := []byte{
- 0x68, 0x69, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20,
- 0x62, 0x75, 0x6c, 0x6c, 0x27, 0x73, 0x20, 0x65,
- 0x79, 0x65,
- }
- if len(a) != len(b) {
- return
- }
- result := make([]byte, len(a))
- for i := 0; i < len(a); i++ {
- result[i] = a[i] ^ b[i]
- }
- fmt.Print("0x")
- for _, val := range result {
- fmt.Printf("%02x", val)
- }
- fmt.Println()
- }