happy_cracking/crypto/
entropy.rs1use anyhow::Result;
2use clap::Subcommand;
3
4#[derive(Subcommand)]
5pub enum EntropyAction {
6 #[command(about = "Calculate Shannon entropy of input")]
7 Analyze {
8 #[arg(help = "Input text")]
9 input: String,
10 },
11}
12
13pub fn run(action: EntropyAction) -> Result<()> {
14 match action {
15 EntropyAction::Analyze { input } => {
16 let entropy = calculate(&input);
17 let classification = classify(entropy);
18 println!("Entropy: {:.4} bits/byte", entropy);
19 println!("Classification: {}", classification);
20 }
21 }
22 Ok(())
23}
24
25pub fn calculate(input: &str) -> f64 {
28 if input.is_empty() {
29 return 0.0;
30 }
31
32 let bytes = input.as_bytes();
33 let len = bytes.len() as f64;
34
35 let mut counts = [0usize; 256];
38 for &b in bytes {
39 counts[b as usize] += 1;
40 }
41
42 let mut entropy = 0.0;
43 for &count in counts.iter() {
44 if count > 0 {
45 let p = count as f64 / len;
46 entropy -= p * p.log2();
47 }
48 }
49
50 entropy
51}
52
53pub fn classify(entropy: f64) -> &'static str {
55 if entropy >= 7.5 {
56 "High (likely encrypted/compressed)"
57 } else if entropy >= 4.0 {
58 "Medium (natural language/code)"
59 } else {
60 "Low (low entropy data)"
61 }
62}