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

REGIONS = [
    ("calibration",0x000000,0x001000),("main_settings",0x002000,0x001000),
    ("channels",0x004000,0x00C000),("zones",0x01C000,0x020000),
    ("contacts",0x05C000,0x010000),("groups",0x07C000,0x003000),
    ("dmr_keys",0x082000,0x003000),("call_log",0x088000,0x00C000),
    ("default_sms",0x094000,0x001000),("msg_drafts",0x095000,0x010000),
    ("msg_inbox",0x0A5000,0x010000),("msg_outbox",0x0B5000,0x010000),
    ("schedules",0x0C6000,0x008000),("dtmf_names",0x0C7000,0x000100),
    ("fm_settings",0x0D6000,0x001000),
    # extended discovered
    ("key_aliases(0xD0000)",0x0D0000,0x006000),
    ("cjk_codepoint_table",0x14C000,0x00B000),
]
def region_of(a):
    for n,s,sz in REGIONS:
        if s<=a<s+sz: return n
    return "UNMAPPED"

def is_word(s):
    """Genuine human string: has a >=3 alpha run and is not a punctuation/char-ramp."""
    s=s.strip()
    if len(s)<2: return False
    if not re.search(r"[A-Za-z]{2,}", s) and not re.search(r"[A-Za-z][a-z]", s):
        # allow pure digit/label like "TG6"
        if not re.search(r"[A-Za-z]", s): return False
    # reject monotone char ramps / repeats
    if re.fullmatch(r"(.)\1*", s): return False
    letters=[c for c in s if c.isalpha()]
    if letters:
        # reject alphabet ramps like KLMNOP / HIJK (consecutive ordinals dominating)
        seq=sum(1 for a,b in zip(letters,letters[1:]) if abs(ord(a)-ord(b))<=1)
        if seq/max(1,len(letters)-1) > 0.8 and len(set(letters))>3:
            return False
    if len(set(s))<=2 and len(s)>=4: return False
    return True

found=[]
# ASCII
run=None
for i,b in enumerate(data):
    if 0x20<=b<=0x7E:
        run=i if run is None else run
    else:
        if run is not None:
            s=data[run:i].decode('latin-1')
            if len(s)>=3 and is_word(s): found.append((run,'ascii',region_of(run),s))
            run=None
# UTF16LE
i=0;n=len(data)
while i<n-1:
    if 0x20<=data[i]<=0x7E and data[i+1]==0:
        j=i;ch=[]
        while j<n-1 and data[j+1]==0 and 0x20<=data[j]<=0x7E:
            ch.append(chr(data[j])); j+=2
        s=''.join(ch)
        if len(s)>=3 and is_word(s): found.append((i,'utf16',region_of(i),s))
        i=max(j,i+2)
    else: i+=1

# dedup identical (addr,text)
seen=set();uniq=[]
for r in found:
    k=(r[0],r[3])
    if k in seen: continue
    seen.add(k); uniq.append(r)

print("TOTAL genuine human-readable strings:", len(uniq))
print("By region:", dict(Counter(r[2] for r in uniq)))
print("By encoding:", dict(Counter(r[1] for r in uniq)))
print()
# collapse Key-N and dump unique text values per region
byreg={}
for a,e,reg,t in uniq: byreg.setdefault(reg,[]).append((a,t))
for reg in byreg:
    vals=byreg[reg]
    print(f"--- {reg} ({len(vals)} strings) ---")
    # show distinct text (first 30)
    shown=0
    for a,t in vals:
        print(f"  0x{a:06X}  {t!r}")
        shown+=1
        if shown>=30:
            print(f"  ... (+{len(vals)-30} more)")
            break
