import struct, collections
DUMP=r"C:/Users/vikto/Documents/Claude/rt-4d/radio-spi-dump.bin"
data=open(DUMP,'rb').read()

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

print("### 0x010000 vs channels 0x004000 (compare first 0x1000) ###")
same=sum(1 for i in range(0x1000) if data[0x010000+i]==data[0x004000+i])
print(f"match to channels@0x4000: {same}/{0x1000} = {100*same/0x1000:.1f}%")
# channel region 0x004000 first records
print("channels@0x004000 head:")
print(hd(0x004000,96))
print("region@0x010000 head:")
print(hd(0x010000,96))

print("\n### 0x03E000 DMRhub context: this looks like a contact/radioid record ###")
print(hd(0x03e000,32))
# Is contacts region at 0x05c000? compare structure - here name at offset 4
print("contacts region @0x05e000 (occupied):")
print(hd(0x05e000,128))

print("\n### 0x0D0000 Key records - 48 byte stride. Compare vs dmr_keys 0x082000 ###")
print("dmr_keys @0x082000:")
print(hd(0x082000,160))
print("encrypt-in-region @0x0D0000 rec0/rec1 detail:")
print(hd(0x0d0000,48))
# check stride: 'Key N' every 0x30
for i in range(5):
    o=0x0d0000+i*0x30
    print(f"rec{i} @{o:08x}: b0={data[o]:02x} b1={data[o+1]:02x} name={data[o+2:o+16]!r} tail={data[o+16:o+24].hex()}")

print("\n### how many Key records populated in 0x0D0000 (+24KB) ###")
cnt=0; last=None
for i in range(24576//0x30):
    o=0x0d0000+i*0x30
    if data[o]!=0xff and data[o]!=0x00:
        cnt+=1; last=i
print(f"populated key records: {cnt}, last idx {last}")

print("\n### 0x126000 record analysis (32-byte stride) ###")
for i in range(8):
    o=0x126000+i*32
    r=data[o:o+32]
    print(f"rec{i} @{o:08x}: {r.hex()}")
# decode fields: bytes 14,15,16 = 19 0a 0e -> 0x19=25,0x0a=10,0x0e=14 => date 2025-10-14
print("byte14-19 as date candidates (YY MM DD HH MM SS):")
for i in range(8):
    o=0x126000+i*32
    r=data[o:o+32]
    print(f"  rec{i}: {r[14]:02d}-{r[15]:02d}-{r[16]:02d} {r[17]:02d}:{r[18]:02d}:{r[19]:02d}  b1(type)={r[1]} dmr_le={struct.unpack('<I',r[6:10])[0]} field10={struct.unpack('<I',r[10:14])[0]}")
# count records
cnt=sum(1 for i in range(20480//32) if data[0x126000+i*32]!=0x00 or any(b!=0 for b in data[0x126000+i*32:0x126000+i*32+16]))
print(f"nonzero-ish records among {20480//32}")
# call_log region is 0x088000; occupied run was 0x092000. compare
print("\ncall_log region occupied @0x092000:")
print(hd(0x092000,128))

print("\n### 0x14C000 GBK decode sample ###")
seg=data[0x14c000:0x14c000+256]
try:
    print(seg.decode('gbk',errors='replace')[:120])
except Exception as e:
    print("err",e)

print("\n### 0x164000 pinyin table structure ###")
# each entry seems 6 bytes ascii pinyin. period ratio peaked at 6
print(hd(0x164000,96))
# Check: is this indexed by GBK char? Look further in
print(hd(0x170000,96))
print("region 0x164000 size 200KB -> 200KB/6 ~ 34000 entries")
