W drugim ćwiczeniu naszym zadaniem jest obliczenie wartości XOR dwóch buforów o jednakowej długości. Mając na uwadze, że tego typu funkcja może przydać się w przyszłości trochę zmodyfikowałem jedno założenie – nasz funkcja będzie przyjmowała dwa bufor które nie muszą być równej długości, krótszy z buforów będzie uzupełniany wartościami 0x0.
def bytes_xor(input_bytes1, input_bytes2):
return bytes([x ^ y for x, y in zip(input_bytes1, input_bytes2)])
def hex_string_xor(input_string1, input_string2):
if len(input_string1) < len(input_string2):
input_string1 += '00'*(len(input_string2) - len(input_string1))
elif len(input_string1) > len(input_string2):
input_string2 += '00'*(len(input_string1) - len(input_string2))
input1 = bytes.fromhex(input_string1)
input2 = bytes.fromhex(input_string2)
return bytes_xor(input1, input2)
Funkcja hex_string_xor przyjmuje dwa dwa bufory z kodami hex. Przed zamianą ich na tablice bajtów porównujemy ich długości i jeżeli ich długości są różne, krótszy z buforów jest uzupełniany wartościami 0x00.
Funkcja bytes_xor iteruje po wszystkich elementach tablic z bajtami i tworzy listę wartości które są wynikami operacji XOR i zwraca tą tablice jako wynik. Można by tą funkcję przepisać w sposób następujący:
1. bytes_iter = zip(input_bytes1, input_bytes2)
2. result = []
3. for (x,y in bytes_iter):
4. result.append(x^y)
5. return result
Wynik byłby taki sam, ale zapis jest mniej zwięzły. Zaletą jest to, że łatwiej zrozumieć co robi ta funkcja.
1. Tworzymy iterator który będzie zwracał krotki (element z pierwszego argumentu, element z drugiego argumentu),
2. Tworzymy zmienną, którą na końcu zwrócimy jako wynik funkcji,
3. i 4. Iterujemy po wszystkich krotkach i do zmiennej result dodajemy wynik operacji XOR na poszczególnych elementach,
5. Zwracamy zmienną result.