Repair project layout and fix Lab024B spectrum detection
This commit is contained in:
198
tests/lab003_crc32.py
Normal file
198
tests/lab003_crc32.py
Normal file
@@ -0,0 +1,198 @@
|
||||
"""
|
||||
Lab003. Обнаружение повреждения пакета с помощью CRC-32.
|
||||
|
||||
Цель:
|
||||
1. Сформировать пакет с CRC-32.
|
||||
2. Проверить исправный пакет.
|
||||
3. Изменить один бит полезной нагрузки.
|
||||
4. Убедиться, что CRC обнаруживает повреждение.
|
||||
"""
|
||||
|
||||
import struct
|
||||
import zlib
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Константы протокола
|
||||
# ============================================================
|
||||
|
||||
SYNC_WORD = 0xAA55
|
||||
PROTOCOL_VERSION = 1
|
||||
MESSAGE_TYPE_TEXT = 1
|
||||
|
||||
HEADER_FORMAT = ">HBBHH"
|
||||
CRC_FORMAT = ">I"
|
||||
|
||||
CRC_SIZE = struct.calcsize(CRC_FORMAT)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Формирование исходного пакета
|
||||
# ============================================================
|
||||
|
||||
message = "ПРИВЕТ SDR"
|
||||
payload = message.encode("utf-8")
|
||||
|
||||
sequence_number = 1
|
||||
payload_length = len(payload)
|
||||
|
||||
header = struct.pack(
|
||||
HEADER_FORMAT,
|
||||
SYNC_WORD,
|
||||
PROTOCOL_VERSION,
|
||||
MESSAGE_TYPE_TEXT,
|
||||
sequence_number,
|
||||
payload_length,
|
||||
)
|
||||
|
||||
# CRC вычисляется по заголовку и полезной нагрузке.
|
||||
packet_without_crc = header + payload
|
||||
|
||||
crc_value = zlib.crc32(packet_without_crc) & 0xFFFFFFFF
|
||||
|
||||
crc_bytes = struct.pack(
|
||||
CRC_FORMAT,
|
||||
crc_value,
|
||||
)
|
||||
|
||||
packet = packet_without_crc + crc_bytes
|
||||
|
||||
|
||||
print("Исходное сообщение:")
|
||||
print(message)
|
||||
|
||||
print("\nCRC-32 исходного пакета:")
|
||||
print(f"0x{crc_value:08X}")
|
||||
|
||||
print("\nПолный пакет:")
|
||||
print(packet.hex(" "))
|
||||
|
||||
print("\nДлина полного пакета:")
|
||||
print(len(packet), "байт")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Проверка исправного пакета
|
||||
# ============================================================
|
||||
|
||||
received_data = packet[:-CRC_SIZE]
|
||||
received_crc_bytes = packet[-CRC_SIZE:]
|
||||
|
||||
(received_crc,) = struct.unpack(
|
||||
CRC_FORMAT,
|
||||
received_crc_bytes,
|
||||
)
|
||||
|
||||
calculated_crc = zlib.crc32(received_data) & 0xFFFFFFFF
|
||||
|
||||
|
||||
print("\n--- Проверка исправного пакета ---")
|
||||
|
||||
print(f"CRC из пакета: 0x{received_crc:08X}")
|
||||
print(f"CRC вычисленный: 0x{calculated_crc:08X}")
|
||||
|
||||
assert received_crc == calculated_crc
|
||||
|
||||
print("Результат: пакет не повреждён.")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Имитация повреждения одного бита
|
||||
# ============================================================
|
||||
|
||||
corrupted_packet = bytearray(packet)
|
||||
|
||||
header_size = struct.calcsize(HEADER_FORMAT)
|
||||
|
||||
# Буква S находится по индексу 13 внутри PAYLOAD.
|
||||
payload_byte_index = 13
|
||||
packet_byte_index = header_size + payload_byte_index
|
||||
|
||||
original_byte = corrupted_packet[packet_byte_index]
|
||||
|
||||
# Меняем младший бит:
|
||||
# S = 0x53
|
||||
# R = 0x52
|
||||
corrupted_packet[packet_byte_index] ^= 0x01
|
||||
|
||||
corrupted_byte = corrupted_packet[packet_byte_index]
|
||||
|
||||
|
||||
print("\n--- Повреждение одного бита ---")
|
||||
|
||||
print(
|
||||
f"До повреждения: "
|
||||
f"0x{original_byte:02X} = {original_byte:08b}"
|
||||
)
|
||||
|
||||
print(
|
||||
f"После повреждения: "
|
||||
f"0x{corrupted_byte:02X} = {corrupted_byte:08b}"
|
||||
)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Проверка повреждённого пакета
|
||||
# ============================================================
|
||||
|
||||
corrupted_data = bytes(
|
||||
corrupted_packet[:-CRC_SIZE]
|
||||
)
|
||||
|
||||
corrupted_crc_bytes = bytes(
|
||||
corrupted_packet[-CRC_SIZE:]
|
||||
)
|
||||
|
||||
(received_crc_after_corruption,) = struct.unpack(
|
||||
CRC_FORMAT,
|
||||
corrupted_crc_bytes,
|
||||
)
|
||||
|
||||
calculated_crc_after_corruption = (
|
||||
zlib.crc32(corrupted_data) & 0xFFFFFFFF
|
||||
)
|
||||
|
||||
|
||||
print("\n--- Проверка повреждённого пакета ---")
|
||||
|
||||
print(
|
||||
f"CRC из пакета: "
|
||||
f"0x{received_crc_after_corruption:08X}"
|
||||
)
|
||||
|
||||
print(
|
||||
f"CRC вычисленный: "
|
||||
f"0x{calculated_crc_after_corruption:08X}"
|
||||
)
|
||||
|
||||
|
||||
if received_crc_after_corruption != calculated_crc_after_corruption:
|
||||
print("\nРезультат: CRC обнаружил повреждение пакета.")
|
||||
else:
|
||||
print("\nРезультат: повреждение не обнаружено.")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Показываем повреждённое сообщение
|
||||
# ============================================================
|
||||
|
||||
corrupted_payload = corrupted_data[header_size:]
|
||||
|
||||
corrupted_message = corrupted_payload.decode("utf-8")
|
||||
|
||||
print("\nСообщение внутри повреждённого пакета:")
|
||||
print(corrupted_message)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Автоматические проверки
|
||||
# ============================================================
|
||||
|
||||
assert corrupted_message == "ПРИВЕТ RDR"
|
||||
|
||||
assert (
|
||||
received_crc_after_corruption
|
||||
!= calculated_crc_after_corruption
|
||||
)
|
||||
|
||||
print("\nПроверка пройдена: CRC-32 обнаружил изменение одного бита.")
|
||||
Reference in New Issue
Block a user