1
\$\begingroup\$

The following algorithm is meant to generate a password from a given set of characters, and a length. Is it biased or predictable in any way? And are graphemes the appropriate Unicode thing to use here, or should I be using Unicode Scalar Values, or just using raw bytes?

// cargo-deps: ring="0.9"

extern crate ring;

use ring::rand::{SystemRandom, SecureRandom};

fn pwgen(
    length: usize,
    chars: &[&str]
) -> String {
    if chars.len() > 256 {
        panic!("Alphabet too large.");
    }

    if chars.len() == 0 {
        panic!("Alphabet too small.");
    }

    let mut result = String::with_capacity(length);
    let mut bytes = vec![0; length];
    let mut complete = 0;

    // The largest multiple of `chars.len()` <= 256.
    // This is necessary to maintain uniformity.
    let bound = 256 - (256 % chars.len());

    while complete < length {
        if SystemRandom.fill(&mut bytes).is_err() {
            panic!("RNG error.");
        }

        for &byte in &bytes {
            let byte = byte as usize;
            if byte < bound {
                result.push_str(chars[byte % chars.len()]);

                complete += 1;
                if complete == length {
                    return result;
                }
            }
        }
    }

    result
}

fn main() {
    println!("{}", pwgen(24, &["←", "→", "↑", "↓"]))
}

Note: The code can be compiled with cargo-script and all error handling code has been replaced with panics to keep it short.

\$\endgroup\$
  • \$\begingroup\$ You haven't added all of the required code. Trying to compile this errors with "cannot find type Error in this scope". I can also see that SystemRandom isn't defined. \$\endgroup\$ – Shepmaster Jun 17 '17 at 14:47
  • \$\begingroup\$ Sorry! I didn't know that the code had to actually compile, just that all of the relevant code had to be added in. :P \$\endgroup\$ – quadrupleslap Jun 17 '17 at 15:23
  • \$\begingroup\$ I can't find the right meta question now, but you are correct: the question doesn't have to include the support code, but at the least you should link to the support code. As one of the few rust reviewers, I prefer to have the entire compilable code because I compile the code to make sure that any suggestions I make actually work. \$\endgroup\$ – Shepmaster Jun 17 '17 at 15:28
  • 1
    \$\begingroup\$ The rule is that enough code has to be included for the question to make sense on its own, even if the links die. An excerpt from real code is fine (Rev 2). You don't have to post a self-contained runnable example, and you certainly don't have to simplify your code for the sake of the question (as you did in Rev 3) — especially if you have to add a disclaimer that it is no longer your real code. \$\endgroup\$ – 200_success Jun 17 '17 at 15:54
  • \$\begingroup\$ Why do you limit the character set to 256 characters? That's way too few for Chinese, Japanese and Korean. \$\endgroup\$ – Roland Illig Jul 10 '17 at 6:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.