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=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=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