Files
Sylpheed/crates/sylpheed-formats/examples/name_from_hash.rs
2026-09-12 16:36:43 +02:00

49 lines
1.8 KiB
Rust

//! 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 -- <hex-hash>…
use sylpheed_formats::hash::name_hash;
fn main() {
let wanted: Vec<u32> = 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");
}