happy-cracking 0.5.0

A fast, comprehensive CTF toolkit for cryptographic encoding/decoding, classic ciphers, hash operations, and analysis tools
Documentation
use anyhow::Result;
use clap::Subcommand;
use std::sync::LazyLock;

#[derive(Subcommand)]
pub enum Crc32Action {
    #[command(about = "Compute CRC32 checksum")]
    Compute {
        #[arg(help = "Input text")]
        input: String,
    },
    #[command(about = "Verify CRC32 checksum")]
    Verify {
        #[arg(help = "Input text")]
        input: String,
        #[arg(long, help = "Expected CRC32 hex checksum")]
        checksum: String,
    },
}

pub fn run(action: Crc32Action) -> Result<()> {
    match action {
        Crc32Action::Compute { input } => {
            println!("{}", compute(&input));
        }
        Crc32Action::Verify { input, checksum } => {
            let computed = compute(&input);
            if computed == checksum.to_lowercase() {
                println!("Match");
            } else {
                println!("Mismatch (expected {}, got {})", checksum, computed);
            }
        }
    }
    Ok(())
}

static CRC32_TABLE: LazyLock<[u32; 256]> = LazyLock::new(|| {
    let mut table = [0u32; 256];
    for i in 0..256u32 {
        let mut crc = i;
        for _ in 0..8 {
            if crc & 1 != 0 {
                crc = (crc >> 1) ^ 0xEDB88320;
            } else {
                crc >>= 1;
            }
        }
        table[i as usize] = crc;
    }
    table
});

pub fn compute_bytes(data: &[u8]) -> u32 {
    let table = &*CRC32_TABLE;
    let mut crc = 0xFFFF_FFFFu32;
    for &byte in data {
        let index = ((crc ^ u32::from(byte)) & 0xFF) as usize;
        crc = (crc >> 8) ^ table[index];
    }
    crc ^ 0xFFFF_FFFF
}

pub fn compute(input: &str) -> String {
    format!("{:08x}", compute_bytes(input.as_bytes()))
}