pub mod brute;
use std::sync::{Arc, Mutex};
use std::time::Duration;
#[allow(dead_code)]
pub fn generate_bruteforce_payloads(chars: &str, max_length: usize) -> Vec<String> {
let progress = Arc::new(Mutex::new(0.0));
brute::generate_bruteforce_payloads(chars, max_length, Some(progress))
}
#[allow(dead_code)]
fn generate_combinations(chars: &str, length: usize) -> Vec<String> {
if length == 0 {
return vec![String::new()];
} else if length == 1 {
return chars.chars().map(|c| c.to_string()).collect();
}
let chunk_size = 10000;
let mut result = Vec::new();
for chunk in brute::generate_combinations_chunked(chars, length, chunk_size) {
result.extend(chunk);
}
result
}
#[allow(dead_code)]
pub fn read_lines_or_literal(data: &str) -> Vec<String> {
match std::fs::read_to_string(data) {
Ok(content) => content.lines().map(|s| s.to_string()).collect(),
Err(_) => vec![data.to_string()],
}
}
#[allow(dead_code)]
pub fn unique(vec: Vec<String>) -> Vec<String> {
let mut seen = std::collections::HashSet::new();
let mut result = Vec::with_capacity(vec.len());
for item in vec {
if seen.insert(item.clone()) {
result.push(item);
}
}
result
}
#[allow(dead_code)]
pub fn format_duration(duration: Duration) -> String {
brute::format_time(duration.as_secs_f64())
}
#[allow(dead_code)]
pub fn estimate_remaining_time(progress_percent: f64, elapsed: Duration) -> String {
let remaining_secs = brute::estimate_time_remaining(progress_percent, elapsed.as_secs_f64());
brute::format_time(remaining_secs)
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Write;
use std::time::Duration;
use tempfile::NamedTempFile;
#[test]
fn test_generate_bruteforce_payloads_simple() {
let chars = "a";
let max_length = 2;
let mut result = generate_bruteforce_payloads(chars, max_length);
result.sort(); let mut expected = vec!["a".to_string(), "aa".to_string()];
expected.sort();
assert_eq!(result, expected);
}
#[test]
fn test_generate_bruteforce_payloads_empty_chars() {
let chars = "";
let max_length = 3;
let result = generate_bruteforce_payloads(chars, max_length);
assert!(
result.is_empty(),
"Expected empty vector for empty charset, got {result:?}"
);
}
#[test]
fn test_generate_bruteforce_payloads_zero_max_length() {
let chars = "ab";
let max_length = 0;
let result = generate_bruteforce_payloads(chars, max_length);
assert!(
result.is_empty(),
"Expected empty vector for max_length 0, got {result:?}"
);
}
#[test]
fn test_read_lines_or_literal_literal() {
let result = read_lines_or_literal("test_string");
assert_eq!(result, vec!["test_string".to_string()]);
}
#[test]
fn test_read_lines_or_literal_file() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file, "line1").unwrap();
writeln!(temp_file, "line2").unwrap();
let result = read_lines_or_literal(temp_file.path().to_str().unwrap());
assert_eq!(result, vec!["line1".to_string(), "line2".to_string()]);
}
#[test]
fn test_read_lines_or_literal_file_not_exists() {
let result = read_lines_or_literal("non_existent_file_for_sure.txt");
assert_eq!(result, vec!["non_existent_file_for_sure.txt".to_string()]);
}
#[test]
fn test_unique_empty() {
let input: Vec<String> = Vec::new();
let result = unique(input);
assert!(result.is_empty(), "Expected empty vector for empty input");
}
#[test]
fn test_unique_no_duplicates() {
let input = vec!["a".to_string(), "b".to_string(), "c".to_string()];
let expected = vec!["a".to_string(), "b".to_string(), "c".to_string()];
let result = unique(input);
assert_eq!(result, expected);
}
#[test]
fn test_unique_with_duplicates() {
let input = vec![
"a".to_string(),
"b".to_string(),
"a".to_string(),
"c".to_string(),
"b".to_string(),
"a".to_string(),
];
let expected = vec!["a".to_string(), "b".to_string(), "c".to_string()];
let result = unique(input);
assert_eq!(
result, expected,
"Duplicates were not removed correctly or order changed"
);
assert_eq!(result.len(), 3);
}
#[test]
fn test_format_duration_seconds() {
assert_eq!(format_duration(Duration::from_secs(5)), "00:00:05");
}
#[test]
fn test_format_duration_minutes() {
assert_eq!(format_duration(Duration::from_secs(125)), "00:02:05"); }
#[test]
fn test_format_duration_hours() {
assert_eq!(format_duration(Duration::from_secs(3661)), "01:01:01"); }
#[test]
fn test_format_duration_zero() {
assert_eq!(format_duration(Duration::ZERO), "00:00:00");
}
}