import struct, collections

DUMP = r"C:/Users/vikto/Documents/Claude/rt-4d/radio-spi-dump.bin"
with open(DUMP,'rb') as f:
    data = f.read()
assert len(data)==4194304

def hexdump(off, n=256, base=None):
    if base is None: base=off
    out=[]
    for i in range(0,n,16):
        chunk=data[off+i:off+i+16]
        if not chunk: break
        hexs=' '.join(f'{b:02x}' for b in chunk)
        asc=''.join(chr(b) if 32<=b<127 else '.' for b in chunk)
        out.append(f'{base+i:08x}  {hexs:<47}  {asc}')
    return '\n'.join(out)

def stats(off, size):
    seg=data[off:off+size]
    c=collections.Counter(seg)
    ff=c.get(0xff,0); zz=c.get(0x00,0)
    return f'size={size} ff={ff}({100*ff/size:.1f}%) 00={zz}({100*zz/size:.1f}%) distinct={len(c)}'

def find_ascii_runs(off, size, minlen=4):
    seg=data[off:off+size]
    runs=[]; cur=b''; start=0
    for i,b in enumerate(seg):
        if 32<=b<127:
            if not cur: start=i
            cur+=bytes([b])
        else:
            if len(cur)>=minlen: runs.append((off+start, cur))
            cur=b''
    if len(cur)>=minlen: runs.append((off+start,cur))
    return runs

def detect_period(off, size, maxp=1024):
    """Find best repeating period by autocorrelation-ish match on a window."""
    seg=data[off:off+min(size,4096)]
    best=[]
    for p in range(2,maxp):
        if p>=len(seg): break
        match=sum(1 for i in range(len(seg)-p) if seg[i]==seg[i+p])
        best.append((match/(len(seg)-p), p))
    best.sort(reverse=True)
    return best[:6]

def compare_region(a_off, b_off, size):
    same=sum(1 for i in range(size) if data[a_off+i]==data[b_off+i])
    return same, size, 100*same/size

regions = [
    ("0x010000", 0x010000, 0x1000),
    ("0x03E000", 0x03E000, 0x1000),
    ("0x0D0000", 0x0D0000, 0x6000),
    ("0x100000", 0x100000, 0x1000),
    ("0x126000", 0x126000, 0x5000),
    ("0x14C000", 0x14C000, 0xB000),
    ("0x164000", 0x164000, 0x32000),
    ("0x325000", 0x325000, 0x1000),
]

for name,off,size in regions:
    print("="*100)
    print(f"REGION {name}  {stats(off,size)}")
    print("-- head --")
    print(hexdump(off,256))
    print("-- period (top ratios) --")
    print(detect_period(off,size))
    runs=find_ascii_runs(off,min(size,0x8000),4)
    print(f"-- ascii runs (first 20 of {len(runs)}) --")
    for r in runs[:20]:
        print(f'  {r[0]:08x}: {r[1][:60]!r}')
    print()
