//! Recover a `sound.pak` TOC name from its hash by generating candidates. //! //! The hash is a Barrett-reduction over the uppercased path, so it cannot be //! inverted — but the naming is regular enough to enumerate. Tries the shapes //! this disc actually uses for sound entries. //! //! cargo run -p sylpheed-formats --example name_from_hash -- … use sylpheed_formats::hash::name_hash; fn main() { let wanted: Vec = std::env::args() .skip(1) .filter_map(|a| u32::from_str_radix(a.trim_start_matches("0x"), 16).ok()) .collect(); assert!(!wanted.is_empty(), "give hashes in hex"); let langs = ["eng", "jpn", ""]; let dirs = [ "", "Movie", "etc", "Voice", "Sound", "BGM", "bgm", "se", "SE", ]; let mut tried = 0usize; let check = |name: String, tried: &mut usize| { *tried += 1; let h = name_hash(&name); if wanted.contains(&h) { println!(" ✅ {h:08x} {name}"); } }; for l in langs { for d in dirs { let pre = match (l.is_empty(), d.is_empty()) { (true, true) => String::new(), (true, false) => format!("{d}\\"), (false, true) => format!("{l}\\"), (false, false) => format!("{l}\\{d}\\"), }; for stem in ["BGM", "bgm", "JNGL", "jngl", "SE", "Static", "VOICE"] { for n in 0..1200u32 { check(format!("{pre}{stem}_{n:03}.slb"), &mut tried); check(format!("{pre}{stem}{n:03}.slb"), &mut tried); } } for bare in ["Static.slb", "static.slb", "SE.slb", "BGM.slb"] { check(format!("{pre}{bare}"), &mut tried); } } } println!("tried {tried} candidate names"); }