pub fn extract_strings(contents: &[u8]) -> Vec<String> {
let mut strings = Vec::new();
let mut current_string = Vec::new();
tracing::debug!("Extracting strings from {} bytes", contents.len());
for &byte in contents {
if byte.is_ascii_graphic() || byte == b' ' || byte == b'\t' {
current_string.push(byte);
} else {
if current_string.len() >= 3 {
if let Ok(s) = String::from_utf8(current_string.clone()) {
if !s.trim().is_empty() && !is_junk_string(&s) {
strings.push(s.trim().to_string());
}
}
}
current_string.clear();
}
}
if current_string.len() >= 3 {
if let Ok(s) = String::from_utf8(current_string) {
if !s.trim().is_empty() && !is_junk_string(&s) {
strings.push(s.trim().to_string());
}
}
}
strings.sort();
strings.dedup();
strings.truncate(50);
tracing::debug!("Extracted {} strings", strings.len());
strings
}
fn is_junk_string(s: &str) -> bool {
s.chars().all(|c| c == '\0' || c == ' ') ||
s.len() > 200 || s.chars().all(|c| c.is_ascii_punctuation())
}