Name Search Catalog rt rl prl - krcenov/RNS510-Map-Viewer GitHub Wiki

Road Name-Search Catalog โ€” eeuz.rt, .rl, .prl

Status: โœ… Cracked (all three, format + validated fields) ยท FLAT_COMPRESSED (see container format)

Three files that together look like a name-search/autocomplete catalog for roads, separate from and much larger than eeu.il. Reader: research/road_index_reader.py.

eeuz.prl โ€” the name strings

("road names" per files.cfg.) A flat, NOT deduplicated concatenation of NUL-terminated name strings, no length prefix. Reference disc: 879,892,357 body bytes, 46,433,034 strings โ€” ~5.3x eeu.rd's own 8,809,081 records, because one real road can get more than one catalog entry.

Example (Linosa, Sicily): eeu.rd stores the bare name "GUITGIA". .prl carries this same road under two entries: verbatim "CONTRADA GUITGIA" and a re-sorted "GUITGIA;CONTRADA" โ€” the core word first, the type word demoted after a ;, so it sorts/searches by the meaningful word. The demotion rule isn't a simple "first word only" ("LATTEA;VIA DELLA VIA" reassembles to eeu.rd's real name "VIA LATTEA" โ€” the whole phrase "VIA DELLA" is demoted) โ€” not fully reverse-engineered, only observed on examples.

eeuz.rl โ€” pointer records

("road list, pointers to names ... in .prl".) Fixed 12-byte records, no gaps, one per .prl string (12 ร— 46,432,934 โ‰ˆ body length, off by ~100 at the very end, unexplained). All fields little-endian:

Bytes Field Confidence
[0:4] candidate index into eeu.rd Strong circumstantial โ€” bounded to eeu.rd's exact record-count range in a 22,000-record sample; direct name cross-check (undoing the ; rewrite) succeeds on 133/300 (44%) of a random sample, most remainder plausibly transliteration differences
[4:7] โ€” Confirmed always 0x00 across the full ~46.4M-record file (reserved/padding)
[7:11] byte offset into decompressed .prl โœ… Exact-match validated at full scale โ€” checked at i = 0, 1, 2, 1000, 100000, 1M, 5M, 10M, 20M, 40M and the last two records: 12/12 exact matches
[11] binary flag (71% are 1, 29% are 0) Unresolved โ€” tested and rejected as "entry has a ; rewrite" (looked clean on 16 records, failed at ~52%/noise-level on 22,000)

eeuz.rt โ€” the search trie

A character-trie with subtree-size "skip" pointers over the same kind of demoted/sort-key name string .prl carries. (An earlier 67-byte divisibility coincidence โ€” "maybe it reuses .rd's record layout" โ€” is refuted; decoding by that layout produces garbage.)

Node format, fixed 19 bytes:

Offset Field Notes
0 uint32 LE subtree_size This node's entire subtree size (itself + descendants), in whole 19-byte units. Leaf = 1. 0 marks a non-character terminator.
4 uint32 LE char_code This node's edge-label character (printable ASCII: A-Z, space, ;, ,, ., digits)
8 uint32 LE reserved Unresolved
12 3 bytes Always observed 0
15 uint32 LE field4 Unresolved โ€” candidate .rd/.rl/.prl leaf pointer, not confirmed

Traversal: a node's children are stored depth-first starting at node_start + 19; to advance to the next sibling, skip forward by the previous child's own subtree_size * 19 bytes.

Validated three ways:

  1. Hand-verified example: node 'D' at body offset 65 (subtree_size=3) jumps 65+19*3=122, landing exactly on node 'M'; nodes 'F' (84) and 'G' (103) are confirmed D's two children.
  2. Pointer hit-rate test: interpreting subtree_size as "jump 19*value bytes, land on another node" scores 72.8% on a 20,000-node sample vs. a 4.23% base rate โ€” the two other same-shaped fields (reserved, field4) only score 15.4%/17.7% under the identical test.
  3. Real cross-referenced vocabulary: walking children and concatenating edge characters spells genuine multi-language street-name fragments, including exact matches to real eeu.typ words (SOKAK, PROEZD, ULITSA, VULYTSIA, CADDESI, VICINALE DEI) and plausible full names ("...TORIO VENETO;VIAO..." โ†’ "VIA VITTORIO VENETO").

Not yet closed: the true global root isn't located (the file's first ~46 bytes don't cleanly decode as this same node shape โ€” you need a starting node offset from elsewhere, e.g. scanning for plausible char_code values); a node's subtree_size doesn't always account for 100% of its own subtree byte-for-byte (most likely a second, wider node variant for non-ASCII/accented characters, not yet decoded); reserved and field4 remain unconfirmed.

Practical relevance (unverified on hardware)

.rl/.prl are 5.3x bigger than eeu.rd and clearly distinct from .il's much smaller single-entry-per-name index; .rt is a real character-trie over the same demoted/sort-key string convention. Plausible but unconfirmed on real hardware: .rt/.rl/.prl back the unit's primary "City โ†’ Street" destination-entry search screen, separately from whatever .il serves. If true, a road added only via .rd/.il (the GUI tool's current "append new road" support) could be unfindable via the unit's normal address-entry UI.

Reader code

research/road_index_reader.py โ€” rt_node(), rt_char(), rt_children(), rt_walk_strings().