1 // Copyright 2018 Developers of the Rand project. 2 // Copyright 2013 The Rust Project Developers. 3 // 4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 5 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license 6 // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your 7 // option. This file may not be copied, modified, or distributed 8 // except according to those terms. 9 10 //! A wrapper around any Read to treat it as an RNG. 11 12 use std::fmt; 13 use std::io::Read; 14 15 use rand_core::{impls, Error, RngCore}; 16 17 18 /// An RNG that reads random bytes straight from any type supporting 19 /// [`std::io::Read`], for example files. 20 /// 21 /// This will work best with an infinite reader, but that is not required. 22 /// 23 /// This can be used with `/dev/urandom` on Unix but it is recommended to use 24 /// [`OsRng`] instead. 25 /// 26 /// # Panics 27 /// 28 /// `ReadRng` uses [`std::io::Read::read_exact`], which retries on interrupts. 29 /// All other errors from the underlying reader, including when it does not 30 /// have enough data, will only be reported through [`try_fill_bytes`]. 31 /// The other [`RngCore`] methods will panic in case of an error. 32 /// 33 /// # Example 34 /// 35 /// ``` 36 /// use rand::Rng; 37 /// use rand::rngs::adapter::ReadRng; 38 /// 39 /// let data = vec![1, 2, 3, 4, 5, 6, 7, 8]; 40 /// let mut rng = ReadRng::new(&data[..]); 41 /// println!("{:x}", rng.gen::<u32>()); 42 /// ``` 43 /// 44 /// [`OsRng`]: crate::rngs::OsRng 45 /// [`try_fill_bytes`]: RngCore::try_fill_bytes 46 #[derive(Debug)] 47 pub struct ReadRng<R> { 48 reader: R, 49 } 50 51 impl<R: Read> ReadRng<R> { 52 /// Create a new `ReadRng` from a `Read`. new(r: R) -> ReadRng<R>53 pub fn new(r: R) -> ReadRng<R> { 54 ReadRng { reader: r } 55 } 56 } 57 58 impl<R: Read> RngCore for ReadRng<R> { next_u32(&mut self) -> u3259 fn next_u32(&mut self) -> u32 { 60 impls::next_u32_via_fill(self) 61 } 62 next_u64(&mut self) -> u6463 fn next_u64(&mut self) -> u64 { 64 impls::next_u64_via_fill(self) 65 } 66 fill_bytes(&mut self, dest: &mut [u8])67 fn fill_bytes(&mut self, dest: &mut [u8]) { 68 self.try_fill_bytes(dest).unwrap_or_else(|err| { 69 panic!( 70 "reading random bytes from Read implementation failed; error: {}", 71 err 72 ) 73 }); 74 } 75 try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>76 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { 77 if dest.is_empty() { 78 return Ok(()); 79 } 80 // Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`. 81 self.reader 82 .read_exact(dest) 83 .map_err(|e| Error::new(ReadError(e))) 84 } 85 } 86 87 /// `ReadRng` error type 88 #[derive(Debug)] 89 pub struct ReadError(std::io::Error); 90 91 impl fmt::Display for ReadError { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result92 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 93 write!(f, "ReadError: {}", self.0) 94 } 95 } 96 97 impl std::error::Error for ReadError { source(&self) -> Option<&(dyn std::error::Error + 'static)>98 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 99 Some(&self.0) 100 } 101 } 102 103 104 #[cfg(test)] 105 mod test { 106 use std::println; 107 108 use super::ReadRng; 109 use crate::RngCore; 110 111 #[test] test_reader_rng_u64()112 fn test_reader_rng_u64() { 113 // transmute from the target to avoid endianness concerns. 114 #[rustfmt::skip] 115 let v = [0u8, 0, 0, 0, 0, 0, 0, 1, 116 0, 4, 0, 0, 3, 0, 0, 2, 117 5, 0, 0, 0, 0, 0, 0, 0]; 118 let mut rng = ReadRng::new(&v[..]); 119 120 assert_eq!(rng.next_u64(), 1 << 56); 121 assert_eq!(rng.next_u64(), (2 << 56) + (3 << 32) + (4 << 8)); 122 assert_eq!(rng.next_u64(), 5); 123 } 124 125 #[test] test_reader_rng_u32()126 fn test_reader_rng_u32() { 127 let v = [0u8, 0, 0, 1, 0, 0, 2, 0, 3, 0, 0, 0]; 128 let mut rng = ReadRng::new(&v[..]); 129 130 assert_eq!(rng.next_u32(), 1 << 24); 131 assert_eq!(rng.next_u32(), 2 << 16); 132 assert_eq!(rng.next_u32(), 3); 133 } 134 135 #[test] test_reader_rng_fill_bytes()136 fn test_reader_rng_fill_bytes() { 137 let v = [1u8, 2, 3, 4, 5, 6, 7, 8]; 138 let mut w = [0u8; 8]; 139 140 let mut rng = ReadRng::new(&v[..]); 141 rng.fill_bytes(&mut w); 142 143 assert!(v == w); 144 } 145 146 #[test] test_reader_rng_insufficient_bytes()147 fn test_reader_rng_insufficient_bytes() { 148 let v = [1u8, 2, 3, 4, 5, 6, 7, 8]; 149 let mut w = [0u8; 9]; 150 151 let mut rng = ReadRng::new(&v[..]); 152 153 let result = rng.try_fill_bytes(&mut w); 154 assert!(result.is_err()); 155 println!("Error: {}", result.unwrap_err()); 156 } 157 } 158