1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//#![cfg_attr(not(feature = "std"), no_std)]
//extern crate no_std_compat as std;
//use std::prelude::v1::*;

#[cfg(feature = "constants")]
#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        let mut x = crate::BruteForce::new(crate::UPPERCASE_CHARS);
        let password = "PASS";
        let mut trys: i32 = 0;
        loop {
            trys = trys + 1;
            let out = x.next();
            if out == password.to_string() {
                println!(">>> SUCCESS ({} times)", trys);
                break;
            }
        }
        assert_eq!(2 + 2, 4);
    }
}

#[cfg(feature = "constants")]
pub const UPPERCASE_CHARS: &'static [char] = &[
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
    'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
];

#[cfg(feature = "constants")]
pub const LOWERCASE_CHARS: &'static [char] = &[
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
    't', 'u', 'v', 'w', 'x', 'y', 'z',
];

#[cfg(feature = "constants")]
pub const NUMBER_CHARS: &'static [char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];

#[cfg(feature = "constants")]
pub const SPECIAL_CHARS: &'static [char] = &[
    '!', '\"', '\'', '?', '\\', '#', '$', '§', '%', '&', '/', '(', ')', '=', '[', ']', '(', ')',
    '{', '}', '´', '`', '<', '>', '€', ',', '.', '-', '_',
];

pub struct BruteForce {
    chars: &'static [char],
    pub current: String,
}

impl BruteForce {
    pub fn new(charset: &'static [char]) -> BruteForce {
        BruteForce {
            chars: charset,
            current: charset[0].to_string(),
        }
    }
    pub fn new_start(charset: &'static [char], start: usize) -> BruteForce {
        let mut start_string = String::new();
        for _ in 0..start {
            start_string.push(charset[0]);
        }
        BruteForce {
            chars: charset,
            current: start_string,
        }
    }
    pub fn next(&mut self) -> String {
        let current_chars: Vec<char> = self.current.chars().collect();
        let mut s: String = String::new();
        let len: usize = *&current_chars.len();
        for n in 0..len {
            let c = &current_chars[n];
            if n != (len - 1) {
                if self.are_next_chars_last(&current_chars, n + 1) {
                    s.push(*self.next_char(c));
                } else {
                    s.push(*c);
                }
            } else if self.is_last_char(c) {
                if self.are_all_chars_last(&current_chars) {
                    s.push(*self.first_char());
                    s.push(*self.first_char());
                } else {
                    s.push(*self.first_char());
                }
            } else {
                s.push(*self.next_char(c));

            }
        }
        self.current = s.clone();
        return s;
    }

    fn are_next_chars_last(&self, chars: &Vec<char>, start: usize) -> bool {
        for n in start..chars.len() {
            if !self.is_last_char(&chars[n]) {
                return false;
            }
        }
        return true;
    }

    fn are_all_chars_last(&self, chars: &Vec<char>) -> bool {
        self.are_next_chars_last(chars, 0)
    }

    fn next_char(&self, c: &char) -> &char {
        let mut is_next: bool = false;
        for ch in self.chars {
            if is_next {
                return ch;
            } else if ch == c {
                is_next = true;
            }
        }
        return &self.chars[0];
    }

    fn is_last_char(&self, c: &char) -> bool {
        self.last_char() == c
    }

    fn first_char(&self) -> &char {
        &self.chars[0]
    }

    fn last_char(&self) -> &char {
        &self.chars[self.chars.len() - 1]
    }
}