Compare commits
No commits in common. "b4ba730818a0335de986b161e685ef27b545114c" and "7a841eac8f645122295493b80b4627319ce305e7" have entirely different histories.
b4ba730818
...
7a841eac8f
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/target
|
|
45
.vscode/launch.json
vendored
45
.vscode/launch.json
vendored
@ -1,45 +0,0 @@
|
|||||||
{
|
|
||||||
// Use IntelliSense to learn about possible attributes.
|
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"type": "lldb",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Debug executable 'all_the_passwords'",
|
|
||||||
"cargo": {
|
|
||||||
"args": [
|
|
||||||
"build",
|
|
||||||
"--bin=all_the_passwords",
|
|
||||||
"--package=all_the_passwords"
|
|
||||||
],
|
|
||||||
"filter": {
|
|
||||||
"name": "all_the_passwords",
|
|
||||||
"kind": "bin"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"args": [],
|
|
||||||
"cwd": "${workspaceFolder}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "lldb",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Debug unit tests in executable 'all_the_passwords'",
|
|
||||||
"cargo": {
|
|
||||||
"args": [
|
|
||||||
"test",
|
|
||||||
"--no-run",
|
|
||||||
"--bin=all_the_passwords",
|
|
||||||
"--package=all_the_passwords"
|
|
||||||
],
|
|
||||||
"filter": {
|
|
||||||
"name": "all_the_passwords",
|
|
||||||
"kind": "bin"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"args": [],
|
|
||||||
"cwd": "${workspaceFolder}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
32
Cargo.lock
generated
32
Cargo.lock
generated
@ -1,32 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "all_the_passwords"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"num-format",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arrayvec"
|
|
||||||
version = "0.7.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "1.0.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-format"
|
|
||||||
version = "0.4.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3"
|
|
||||||
dependencies = [
|
|
||||||
"arrayvec",
|
|
||||||
"itoa",
|
|
||||||
]
|
|
10
Cargo.toml
10
Cargo.toml
@ -1,10 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "all_the_passwords"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
num-format = "0.4.4"
|
|
||||||
|
|
117
src/main.rs
117
src/main.rs
@ -1,117 +0,0 @@
|
|||||||
use std::io::{stderr, Write};
|
|
||||||
use std::thread::{self, sleep};
|
|
||||||
use std::time::{Duration, Instant};
|
|
||||||
|
|
||||||
use num_format::{Locale, ToFormattedString};
|
|
||||||
|
|
||||||
const ALL_CHARS: &'static str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.<>/?;':\"[]{}\\|-=_+`~!@#$%^&*()";
|
|
||||||
const LEN: usize = 4;
|
|
||||||
|
|
||||||
static mut SOFAR: u128 = 0;
|
|
||||||
static mut TOTAL: usize = 0;
|
|
||||||
|
|
||||||
/// Pseudo main
|
|
||||||
///
|
|
||||||
/// Starts the number crunching (blocking on main thread!) and the
|
|
||||||
/// timer thread which watches the main thread while
|
|
||||||
/// reporting statistics about it.
|
|
||||||
fn start(char_list: &str, output_len: usize) {
|
|
||||||
/// Flag to communicate between main (combination crunching) and
|
|
||||||
/// timer threads.
|
|
||||||
static mut IS_DONE: bool = false;
|
|
||||||
|
|
||||||
let start = Instant::now();
|
|
||||||
|
|
||||||
// Just to report stats
|
|
||||||
let timer = thread::spawn(move || {
|
|
||||||
let mut out = stderr();
|
|
||||||
|
|
||||||
while unsafe { !IS_DONE } {
|
|
||||||
let mut elapsed = start.elapsed().as_secs() as u128;
|
|
||||||
// prevent div by zero err
|
|
||||||
if elapsed == 0 { elapsed = 1; }
|
|
||||||
|
|
||||||
let sofar = unsafe {SOFAR};
|
|
||||||
// output P/s
|
|
||||||
let _ = out.write(
|
|
||||||
format!("\rCalculated {} possibilities thus far, at {} p/s",
|
|
||||||
sofar.to_formatted_string(&Locale::en_NA),
|
|
||||||
(sofar / elapsed).to_formatted_string(&Locale::en_NA),
|
|
||||||
).as_bytes());
|
|
||||||
let _ = out.flush();
|
|
||||||
sleep(Duration::from_secs(1));
|
|
||||||
|
|
||||||
/*
|
|
||||||
// output remaining time
|
|
||||||
// I haven't tested to see if this timer is somewhat accurate...
|
|
||||||
// This is code I stole of reddit... what am I doing?
|
|
||||||
let remaining = unsafe { TOTAL as u128 / (sofar / elapsed) };
|
|
||||||
let sec = remaining % 60;
|
|
||||||
let min = (remaining / 60) % 60;
|
|
||||||
let hrs = (remaining / 60) / 60;
|
|
||||||
|
|
||||||
let _ = out.write(
|
|
||||||
// TODO clear the whole line, don't just put cursor to the begining...
|
|
||||||
format!("\r{}%, {}h:{}m:{}s remaining ",
|
|
||||||
unsafe { sofar / TOTAL as u128 },
|
|
||||||
hrs, min, sec
|
|
||||||
).as_bytes());
|
|
||||||
let _ = out.flush();
|
|
||||||
sleep(Duration::from_secs(1));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// starting with the blank string is important
|
|
||||||
calc(char_list, &"", output_len);
|
|
||||||
|
|
||||||
unsafe { IS_DONE = true; }
|
|
||||||
timer.join().unwrap();
|
|
||||||
|
|
||||||
eprintln!("\r{}ms to calculate the permutations (p) for {} chars (n) across {} slots (r).", start.elapsed().as_millis().to_formatted_string(&Locale::en_NA), char_list.len(), output_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// All the status messages are printed on stderr
|
|
||||||
// This way you can pipe the actual permutations into
|
|
||||||
// a file whilst still getting debug messages.
|
|
||||||
let t = (ALL_CHARS.len() as u128).pow(LEN.try_into().unwrap());
|
|
||||||
unsafe { TOTAL = t as usize };
|
|
||||||
eprintln!(
|
|
||||||
"Calculating {} combinations...\n(Number may be trunkated if too large)\n",
|
|
||||||
unsafe { TOTAL }.to_formatted_string(&Locale::en_NA)
|
|
||||||
);
|
|
||||||
|
|
||||||
start(ALL_CHARS, LEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Recurseively create and print every combination of
|
|
||||||
/// `choices` chars inside a string of `len` length.
|
|
||||||
///
|
|
||||||
///
|
|
||||||
/// * `choices` string containing all the chars you wish
|
|
||||||
/// to build random strings with.
|
|
||||||
///
|
|
||||||
/// * `prefix` should be a blank string `""` unless you
|
|
||||||
/// actually want a prefix on every output. This variable is
|
|
||||||
/// mainly used within the recursive nature of the funciton.
|
|
||||||
///
|
|
||||||
/// * `len` the size that all the output strings wil be.
|
|
||||||
fn calc(choices: &str, prefix: &str, len: usize) {
|
|
||||||
let need_to_fill = len - prefix.len();
|
|
||||||
match need_to_fill {
|
|
||||||
// the last char in the sequence, time to print
|
|
||||||
1 => {
|
|
||||||
for i in choices.chars() {
|
|
||||||
println!("{}{}", prefix, i);
|
|
||||||
unsafe { SOFAR = SOFAR + 1 };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// need to recurse farther into the sequence
|
|
||||||
_ => {
|
|
||||||
for i in choices.chars() {
|
|
||||||
calc(choices, &(prefix.to_string() + &i.to_string()), len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user