# -*- coding: utf-8 -*- # Точное сравнение CRC-схем на бит-слипе. crc8 как в IR_config.cpp. # ВАЖНО: CRC в протоколе считается над БАЙТАМИ данных (sync НЕ входит — подтверждено кодом), # поэтому здесь sync в CRC-математику не включён (это корректно для оценки самой CRC). # Второй ниббл — СО СЦЕПКОЙ: poly2 над (data + crc1_байт), как в оригинале crcCheck. # Сквозной анализ с sync-фильтром требует модели FSM декодера (resync/‘исправление лишнего нуля’) — см. заметку. import random random.seed(3) POLY1=0x31; POLY2=0x8C def crc8(d,poly): c=0xFF for b in d: c^=b for _ in range(8): c=((c<<1)^poly)&0xFF if c&0x80 else (c<<1)&0xFF return c def fold4(x): return (x^(x>>4))&0x0F def single(d): return (crc8(d,POLY1),) def double(d): c1=crc8(d,POLY1); return (c1, crc8(d+[c1],POLY2)) # текущая 2 байта, сцепка def combo_indep(d): return ((fold4(crc8(d,POLY1))<<4)|fold4(crc8(d,POLY2)),) # 1 байт, БЕЗ сцепки def combo_chain(d): c1=crc8(d,POLY1); return ((fold4(c1)<<4)|fold4(crc8(d+[c1],POLY2)),) # 1 байт, СО сцепкой (как ориг.) def bitsof(d): return [x for b in d for x in [(b>>(7-j))&1 for j in range(8)]] def bytesof(b): return [int(''.join(map(str,b[i:i+8])),2) for i in range(0,len(b),8)] def slip(d,p): b=bitsof(d); return bytesof(b[:p]+b[p+1:]+[0]) S=[("single 1б",single),("double 2б (текущая, сцепка)",double), ("combo 1б БЕЗ сцепки",combo_indep),("combo 1б СО сцепкой (как ориг.)",combo_chain)] for L in (4,6,8): und={n:0 for n,_ in S}; ch=0 for _ in range(300000): d=[random.randint(0,255) for _ in range(L)]; p=random.randint(L*2,L*6) c=slip(d,p) if c==d: continue ch+=1 for n,f in S: if f(c)==f(d): und[n]+=1 print(f"данные {L}б, {ch} слипов:") for n,_ in S: print(f" {n:34s}: {und[n]/ch*100:.4f}% необнаружено")