mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-24 20:48:55 +00:00
rand_ish: Generate random string from SimpleRng
Devices may not have access to /dev/urandom so refactor the random string generation code so that it can also be used by SimpleRng. Also implement Iterator for SimpleRng to make the string generator implementation easier. BUG=b:152806644,b:159285544 TEST=unit tests Change-Id: I245c90dc44cfa53a7e12343925b1e04a5df55255 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2260252 Auto-Submit: Chirantan Ekbote <chirantan@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Zach Reizner <zachr@chromium.org> Reviewed-by: Stephen Barber <smbarber@chromium.org> Commit-Queue: Chirantan Ekbote <chirantan@chromium.org>
This commit is contained in:
parent
708e3a63b9
commit
da69086e9f
1 changed files with 19 additions and 9 deletions
|
@ -25,27 +25,37 @@ impl SimpleRng {
|
|||
self.seed = a.wrapping_mul(self.seed).wrapping_add(c);
|
||||
self.seed
|
||||
}
|
||||
|
||||
/// Generate a random alphanumeric string.
|
||||
pub fn str(&mut self, len: usize) -> String {
|
||||
self.filter_map(|v| uniform_sample_ascii_alphanumeric(v as u8))
|
||||
.take(len)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for SimpleRng {
|
||||
type Item = u64;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
Some(self.rng())
|
||||
}
|
||||
}
|
||||
|
||||
// Uniformly samples the ASCII alphanumeric characters given a random variable. If an `Err` is
|
||||
// passed in, the error is returned as `Some(Err(...))`. If the the random variable can not be used
|
||||
// to uniformly sample, `None` is returned.
|
||||
fn uniform_sample_ascii_alphanumeric(
|
||||
b: Result<u8, std::io::Error>,
|
||||
) -> Option<Result<char, std::io::Error>> {
|
||||
fn uniform_sample_ascii_alphanumeric(b: u8) -> Option<char> {
|
||||
const ASCII_CHARS: &[u8] = b"\
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
|
||||
abcdefghijklmnopqrstuvwxyz\
|
||||
0123456789";
|
||||
let char_index = match b {
|
||||
Ok(c) => c as usize,
|
||||
Err(e) => return Some(Err(e)),
|
||||
};
|
||||
let char_index = b as usize;
|
||||
// Throw away numbers that would cause sampling bias.
|
||||
if char_index >= ASCII_CHARS.len() * 4 {
|
||||
None
|
||||
} else {
|
||||
Some(Ok(ASCII_CHARS[char_index % ASCII_CHARS.len()] as char))
|
||||
Some(ASCII_CHARS[char_index % ASCII_CHARS.len()] as char)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +63,7 @@ fn uniform_sample_ascii_alphanumeric(
|
|||
pub fn urandom_str(len: usize) -> io::Result<String> {
|
||||
File::open("/dev/urandom")?
|
||||
.bytes()
|
||||
.filter_map(uniform_sample_ascii_alphanumeric)
|
||||
.filter_map(|b| b.map(uniform_sample_ascii_alphanumeric).transpose())
|
||||
.take(len)
|
||||
.collect::<io::Result<String>>()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue