mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-10 20:19:07 +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 = a.wrapping_mul(self.seed).wrapping_add(c);
|
||||||
self.seed
|
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
|
// 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
|
// passed in, the error is returned as `Some(Err(...))`. If the the random variable can not be used
|
||||||
// to uniformly sample, `None` is returned.
|
// to uniformly sample, `None` is returned.
|
||||||
fn uniform_sample_ascii_alphanumeric(
|
fn uniform_sample_ascii_alphanumeric(b: u8) -> Option<char> {
|
||||||
b: Result<u8, std::io::Error>,
|
|
||||||
) -> Option<Result<char, std::io::Error>> {
|
|
||||||
const ASCII_CHARS: &[u8] = b"\
|
const ASCII_CHARS: &[u8] = b"\
|
||||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
|
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
|
||||||
abcdefghijklmnopqrstuvwxyz\
|
abcdefghijklmnopqrstuvwxyz\
|
||||||
0123456789";
|
0123456789";
|
||||||
let char_index = match b {
|
let char_index = b as usize;
|
||||||
Ok(c) => c as usize,
|
|
||||||
Err(e) => return Some(Err(e)),
|
|
||||||
};
|
|
||||||
// Throw away numbers that would cause sampling bias.
|
// Throw away numbers that would cause sampling bias.
|
||||||
if char_index >= ASCII_CHARS.len() * 4 {
|
if char_index >= ASCII_CHARS.len() * 4 {
|
||||||
None
|
None
|
||||||
} else {
|
} 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> {
|
pub fn urandom_str(len: usize) -> io::Result<String> {
|
||||||
File::open("/dev/urandom")?
|
File::open("/dev/urandom")?
|
||||||
.bytes()
|
.bytes()
|
||||||
.filter_map(uniform_sample_ascii_alphanumeric)
|
.filter_map(|b| b.map(uniform_sample_ascii_alphanumeric).transpose())
|
||||||
.take(len)
|
.take(len)
|
||||||
.collect::<io::Result<String>>()
|
.collect::<io::Result<String>>()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue