فهرست منبع

add the RUST version

Pat Beirne 8 ماه پیش
والد
کامیت
6145877086
2فایلهای تغییر یافته به همراه140 افزوده شده و 0 حذف شده
  1. 9 0
      pwgen/Cargo.toml
  2. 131 0
      pwgen/src/main.rs

+ 9 - 0
pwgen/Cargo.toml

@@ -0,0 +1,9 @@
+[package]
+name = "pwgen"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+rand = "0.8.4"

+ 131 - 0
pwgen/src/main.rs

@@ -0,0 +1,131 @@
+/* pwgen
+
+  generate passwords in useful ways
+
+usage: pwgen -c [number of phrases, default=1]
+      pwgen [len default=20] [number of phrases, default=1]     //no conjunctions
+    
+*/
+use std::env;
+use std::fs::File;
+use std::io::{BufReader, BufRead};
+use rand::Rng;
+
+#[derive(Debug)]
+struct Settings {
+  target_len: usize,
+  target_len_set: bool,
+  use_conjunction: bool,
+  number: u16,
+  help: bool,
+  pad_chars: String,
+  // debug: bool,
+}
+
+const CONJUNCTIONS: &[&str] = &["and", "and a", "and the","or", 
+	"or the", "or a", "with a", "with", "with the", "by a", "by the",
+   "on a", "on the","on", "in a", "in the", "in",
+   "for", "for a", "for the", "but", "so"];
+
+
+
+fn main() -> std::io::Result<()> {
+  let mut set = Settings {
+    number: 1, 
+    target_len: 20, target_len_set: false, 
+    use_conjunction: false, 
+    // debug: false,
+    help: false, 
+		// owasp.org/www-community/password-special-characters
+    pad_chars: " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".to_string() 
+		// princeton IT
+	 //pad_chars: " ~`!@#$%^&*()-_+={}[]|\\;:\"<>,./?".to_string()
+  };
+
+  let args: Vec<String> = env::args().collect();
+  parse_args(&args,&mut set);
+  if set.help == true { 
+    usage();
+    return Ok(())
+  }
+  
+  let file = File::open("/usr/share/dict/words")
+		.expect("Dictionary file /usr/share/dict/words not found");
+  let buf = BufReader::new(file);
+  let words: Vec<String> = buf.lines().map(|x| x.expect("bad line")).collect();
+  let num_words = words.len();
+  
+	let mut rng = rand::thread_rng();
+	    
+	for _i in 0 .. set.number {
+		let w0 = &words[rng.gen_range(0 .. num_words)];
+		let w1 = &words[rng.gen_range(0 .. num_words)];
+		let w2 = &words[rng.gen_range(0 .. num_words)];
+		let w3 = &words[rng.gen_range(0 .. num_words)];
+		
+		let padding = set.pad_chars.chars()
+			.nth(rng.gen_range(0 .. set.pad_chars.len()))
+			.unwrap()
+			.to_string();
+
+		if set.use_conjunction {
+		  let mut conj = CONJUNCTIONS[rng.gen_range(0 .. CONJUNCTIONS.len())].to_string();
+		  if conj.ends_with(" a") && w1.starts_with(|x| "aAeEiIoOuU".find(x).is_some()) {
+			  conj.push('n');
+		  }
+		  println!("{} {} {}", w0, conj, w1);
+
+		} else {
+
+			let mut pw = format!("{}{}{}",w0,padding,w1);
+			if pw.len() < set.target_len {
+				pw = format!("{}{}{}",pw,padding,w2);
+				if pw.len() < set.target_len {
+					pw = format!("{}{}{}",pw,padding,w3);
+				}
+			}
+			println!("{}",pw);
+		}
+  }
+  Ok(())
+}
+
+fn usage() {
+  println!("pygen    v1.0    generate passphrase; inspired by xkcd/936
+Usage: pygen [-p | -P | -n | -N] [-L <n> | --length <n>] [num_phrases]
+       pygen -c [num_phrases]
+       pygen -h | --help
+    -p         pad with only spaces (for smartphone)
+    -P         pad with spaces, period, comma (for smartphone)
+    -n         pad with numbers
+    -N         pad with numbers, spaces, periods, comma
+    -L --length     add extra filler to reach length (default=20)
+    -c         make 2 word phrases with a conjunction filler
+    num_phrases make multiple passphrases (default=1)");
+
+}
+
+
+fn parse_args(a:&Vec<String>, s:&mut Settings) {
+  // dbg!(a);
+  for item in &a[1 .. ] {
+	  if s.target_len_set {
+		  s.target_len_set = true;
+		  s.target_len = item.parse::<usize>().expect("length must be a positive integer");
+		  continue;
+		}
+
+    match (item.as_str(),item.parse::<u16>()) {
+      ("-p", ..) => s.pad_chars = " ".to_string(),
+      ("-P", ..) => s.pad_chars = " ,.".to_string(),
+      ("-n", ..) => s.pad_chars = "0123456789".to_string(),
+      ("-N", ..) => s.pad_chars = " ,.0123456789".to_string(),
+      ("-L", ..) | ("--length", ..) => s.target_len_set = true, 
+      ("-c", ..) => s.use_conjunction = true,
+      ("-h", ..) | ("--help", ..) => s.help = true,
+      (.., Ok(x)) => s.number = x,
+      _ => println!("invalid option: {}", item),
+    }
+  }
+  //dbg!(s);
+}