@@ -36,6 +36,37 @@ use serde::{Serialize, Deserialize};
36
36
/// .collect();
37
37
/// println!("Random chars: {}", chars);
38
38
/// ```
39
+ ///
40
+ /// # Passwords
41
+ ///
42
+ /// We caution that strings produced by sampling `Alphanumeric` tend not
43
+ /// to be particularly memorable when used as passwords by humans.
44
+ /// Instead, we suggest that human memorable passwords be created by
45
+ /// drawing words independently and uniformly at random from a large wordlist.
46
+ ///
47
+ /// Each random word contributes `log2(wordlist_length)` bits of entropy.
48
+ ///
49
+ /// Among the widely reviewed wordlists, there are [Diceware](https://en.wikipedia.org/wiki/Diceware)
50
+ /// wordlists for many major langauges, including some from security
51
+ /// organizations like the E.F.F., and many of which further facilitate
52
+ /// memorability by avoiding homophones and words with tricky spelling.
53
+ ///
54
+ /// There exists [several crates](https://crates.io/search?q=diceware) for
55
+ /// this but `rand::seq::SliceRandom::choose` works too:
56
+ /// ```
57
+ /// # use rand::Rng;
58
+ /// #[allow(dead_code)]
59
+ /// pub fn make_password<R: Rng>(wordlist: &[impl ::core::borrow::Borrow<str>], entropy: u32, rng: &mut R) -> String {
60
+ /// use rand::seq::SliceRandom;
61
+ /// use core::convert::TryInto;
62
+ /// let entropy: f64 = entropy.into();
63
+ /// let l: u32 = wordlist.len().try_into().unwrap();
64
+ /// assert!( l > 0 );
65
+ /// let l: f64 = l.into();
66
+ /// let l = (entropy / l.log2()).ceil() as usize;
67
+ /// (0..l).map(|_| wordlist.choose(rng).unwrap().borrow() ).collect::<String>()
68
+ /// }
69
+ /// ```
39
70
#[ derive( Debug ) ]
40
71
#[ cfg_attr( feature = "serde1" , derive( Serialize , Deserialize ) ) ]
41
72
pub struct Alphanumeric ;
0 commit comments