const MIN_BLOB_LEN: usize = 256;
fn is_base64ish(c: char) -> bool {
c.is_ascii_alphanumeric() || matches!(c, '+' | '/' | '=' | '-' | '_')
}
pub fn detect(content: &str) -> Option<&'static str> {
let lc = content.to_ascii_lowercase();
let has = |needle: &str| lc.contains(needle);
if (has("\"type\":\"reasoning\"") || has("\"type\": \"reasoning\"")) && has("encrypted_content")
{
return Some("openai-style reasoning block with encrypted_content");
}
if (has("\"type\":\"redacted_thinking\"") || has("\"type\": \"redacted_thinking\""))
&& has("\"data\"")
{
return Some("anthropic-style redacted_thinking block with opaque data");
}
if has("reasoning.encrypted_content") || has("encrypted_reasoning") {
return Some("provider encrypted-reasoning field");
}
if longest_base64ish_run_looks_opaque(content) {
return Some("long high-entropy base64-shaped blob");
}
None
}
fn longest_base64ish_run_looks_opaque(content: &str) -> bool {
let chars: Vec<char> = content.chars().collect();
let mut i = 0;
while i < chars.len() {
if is_base64ish(chars[i]) {
let start = i;
while i < chars.len() && is_base64ish(chars[i]) {
i += 1;
}
let run = &chars[start..i];
if run.len() >= MIN_BLOB_LEN {
let has_upper = run.iter().any(|c| c.is_ascii_uppercase());
let has_lower = run.iter().any(|c| c.is_ascii_lowercase());
let has_digit = run.iter().any(|c| c.is_ascii_digit());
if has_upper && has_lower && has_digit {
return true;
}
}
} else {
i += 1;
}
}
false
}
#[cfg(test)]
mod tests {
use super::*;
fn blob(n: usize) -> String {
const ALPHA: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
(0..n).map(|k| ALPHA[k % ALPHA.len()] as char).collect()
}
#[test]
fn openai_reasoning_block_is_flagged() {
let s = r#"{"type":"reasoning","summary":[],"encrypted_content":"gAAAAAB..."}"#;
assert!(detect(s).is_some());
}
#[test]
fn anthropic_redacted_thinking_is_flagged() {
let s = r#"{"type":"redacted_thinking","data":"EvwBCkYI...opaque..."}"#;
assert!(detect(s).is_some());
}
#[test]
fn bare_long_blob_is_flagged() {
assert!(detect(&blob(300)).is_some());
let wrapped = format!("assistant said: {} -- end", blob(300));
assert!(detect(&wrapped).is_some());
}
#[test]
fn ordinary_prose_is_not_flagged() {
let s = "The user prefers dark mode and lives in Berlin. Remind them at 9am.";
assert!(detect(s).is_none());
}
#[test]
fn short_token_is_not_flagged() {
assert!(detect(&blob(64)).is_none());
}
#[test]
fn long_lowercase_hex_is_not_flagged() {
let hex: String = std::iter::repeat_n("abcdef0123456789", 32).collect();
assert_eq!(hex.len(), 512);
assert!(detect(&hex).is_none());
}
}