94 lines
2.4 KiB
Python
94 lines
2.4 KiB
Python
import binascii
|
|
|
|
RAW_FILE = r"u:\PycharmProjects\NewsGroups\downloads\raw\part_001.raw"
|
|
|
|
# --------------------------------------------------
|
|
# yEnc decoder (offline, minimal, correct)
|
|
# --------------------------------------------------
|
|
def yenc_decode(lines: list[bytes]) -> bytes:
|
|
out = bytearray()
|
|
|
|
for line in lines:
|
|
# undo NNTP dot-stuffing
|
|
if line.startswith(b".."):
|
|
line = line[1:]
|
|
elif line.startswith(b"."):
|
|
line = line[1:]
|
|
|
|
i = 0
|
|
while i < len(line):
|
|
c = line[i]
|
|
if c == ord("="):
|
|
i += 1
|
|
c = (line[i] - 64) & 0xFF
|
|
out.append((c - 42) & 0xFF)
|
|
i += 1
|
|
|
|
return bytes(out)
|
|
|
|
# --------------------------------------------------
|
|
# 1. read RAW file
|
|
# --------------------------------------------------
|
|
with open(RAW_FILE, "rb") as f:
|
|
raw_lines = f.read().splitlines()
|
|
|
|
print(f"📄 RAW lines: {len(raw_lines)}")
|
|
|
|
# --------------------------------------------------
|
|
# 2. split parts
|
|
# --------------------------------------------------
|
|
ybegin = None
|
|
ypart = None
|
|
yend = None
|
|
data_lines = []
|
|
|
|
for line in raw_lines:
|
|
if line.startswith(b"=ybegin"):
|
|
ybegin = line.decode(errors="replace")
|
|
continue
|
|
|
|
if line.startswith(b"=ypart"):
|
|
ypart = line.decode(errors="replace")
|
|
continue
|
|
|
|
if line.startswith(b"=yend"):
|
|
yend = line.decode(errors="replace")
|
|
continue
|
|
|
|
data_lines.append(line)
|
|
|
|
print("🧾 ybegin:", ybegin)
|
|
print("🧾 ypart :", ypart)
|
|
print("🧾 yend :", yend)
|
|
print(f"📦 DATA lines: {len(data_lines)}")
|
|
|
|
# --------------------------------------------------
|
|
# 3. decode yEnc DATA
|
|
# --------------------------------------------------
|
|
decoded = yenc_decode(data_lines)
|
|
|
|
print(f"📦 Decoded bytes: {len(decoded)}")
|
|
|
|
# --------------------------------------------------
|
|
# 4. extract pcrc32
|
|
# --------------------------------------------------
|
|
pcrc = None
|
|
if "pcrc32=" in yend:
|
|
pcrc = yend.split("pcrc32=")[1].strip()
|
|
|
|
if not pcrc:
|
|
raise RuntimeError("No pcrc32 found")
|
|
|
|
# --------------------------------------------------
|
|
# 5. compute CRC32
|
|
# --------------------------------------------------
|
|
crc_calc = f"{binascii.crc32(decoded) & 0xffffffff:08x}"
|
|
|
|
print(f"🔎 CRC expected: {pcrc}")
|
|
print(f"🔎 CRC computed: {crc_calc}")
|
|
|
|
if crc_calc == pcrc:
|
|
print("✅ CRC MATCH — PART IS PERFECT")
|
|
else:
|
|
print("❌ CRC MISMATCH — DATA IS BROKEN")
|