Files
SDR-Rover/tests/lab002_bit_corruption.py

153 lines
4.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Lab002, часть 2.
Повреждение одного бита пакета без контроля целостности.
Цель:
1. Сформировать цифровой пакет.
2. Намеренно изменить один бит полезной нагрузки.
3. Разобрать повреждённый пакет.
4. Убедиться, что без CRC повреждение не обнаруживается.
"""
import struct
# ============================================================
# Константы протокола
# ============================================================
SYNC_WORD = 0xAA55
PROTOCOL_VERSION = 1
MESSAGE_TYPE_TEXT = 1
HEADER_FORMAT = ">HBBHH"
# ============================================================
# Формирование исходного пакета
# ============================================================
message = "ПРИВЕТ SDR"
payload = message.encode("utf-8")
sequence_number = 1
message_type = MESSAGE_TYPE_TEXT
payload_length = len(payload)
header = struct.pack(
HEADER_FORMAT,
SYNC_WORD,
PROTOCOL_VERSION,
message_type,
sequence_number,
payload_length,
)
packet = header + payload
print("Исходное сообщение:")
print(message)
print("\nИсходный пакет:")
print(packet.hex(" "))
# ============================================================
# Имитация повреждения пакета
# ============================================================
# bytes нельзя изменять напрямую.
# Поэтому преобразуем пакет в изменяемый массив bytearray.
corrupted_packet = bytearray(packet)
header_size = struct.calcsize(HEADER_FORMAT)
# В строке "ПРИВЕТ SDR":
#
# "ПРИВЕТ" занимает 12 байтов UTF-8,
# пробел занимает 1 байт,
# буква S находится по индексу 13 внутри PAYLOAD.
payload_byte_index = 13
# Полный индекс внутри пакета:
packet_byte_index = header_size + payload_byte_index
original_byte = corrupted_packet[packet_byte_index]
# XOR с 0x01 изменяет младший бит:
#
# 0x53 = 01010011 = S
# 0x52 = 01010010 = R
corrupted_packet[packet_byte_index] ^= 0x01
corrupted_byte = corrupted_packet[packet_byte_index]
print("\nИзменяемый байт внутри пакета:")
print(
f"До повреждения: "
f"{original_byte:3d} "
f"= 0x{original_byte:02X} "
f"= {original_byte:08b}"
)
print(
f"После повреждения: "
f"{corrupted_byte:3d} "
f"= 0x{corrupted_byte:02X} "
f"= {corrupted_byte:08b}"
)
print("\nПовреждённый пакет:")
print(bytes(corrupted_packet).hex(" "))
# ============================================================
# Разбор повреждённого пакета
# ============================================================
received_header = corrupted_packet[:header_size]
received_payload = corrupted_packet[header_size:]
(
received_sync,
received_version,
received_type,
received_sequence,
received_length,
) = struct.unpack(HEADER_FORMAT, received_header)
# ============================================================
# Проверки структуры
# ============================================================
assert received_sync == SYNC_WORD
assert received_version == PROTOCOL_VERSION
assert received_type == MESSAGE_TYPE_TEXT
assert received_sequence == sequence_number
assert received_length == len(received_payload)
print("\nВсе проверки заголовка пройдены.")
restored_message = bytes(received_payload).decode("utf-8")
print("\nСообщение после повреждения:")
print(restored_message)
print("\nИсходное сообщение:")
print(message)
# ============================================================
# Проверка результата эксперимента
# ============================================================
assert restored_message != message
print("\nПовреждение данных произошло.")
print("Но заголовок и длина пакета остались правильными.")
print("Без CRC приёмник не смог определить ошибку.")