tinymt/
lib.rs

1//!
2//! ```rust
3//! use tinymt::{TinyMT64, TinyMT64Seed, TinyMT32};
4//! use rand::{Rng, SeedableRng};
5//!
6//! // from nondeterministic seed
7//! let mut random = TinyMT64::from_entropy();
8//! let rn = random.gen_range(0.0..1.0);
9//! assert!((0.0..1.0).contains(&rn));
10//!
11//! // from deterministic seed (reproduction of random number sequence is possible)
12//! let mut random = TinyMT64::from_seed(TinyMT64Seed::from(0u64));
13//! let rn = random.gen_range(0.0..1.0);
14//! assert!((0.0..1.0).contains(&rn));
15//! ```
16//!
17//! This crate is `no_std` compatible.
18//!
19#![no_std]
20use core::cmp::min;
21
22use rand::{Error, RngCore, SeedableRng};
23
24pub mod tinymt32;
25pub mod tinymt64;
26
27#[derive(Default)]
28pub struct TinyMT64Seed(pub [u8; 8]);
29
30impl From<u64> for TinyMT64Seed {
31  fn from(seed: u64) -> Self {
32    TinyMT64Seed(seed.to_le_bytes())
33  }
34}
35
36impl From<TinyMT64Seed> for u64 {
37  fn from(seed: TinyMT64Seed) -> Self {
38    u64::from_le_bytes(seed.0)
39  }
40}
41
42impl AsMut<[u8]> for TinyMT64Seed {
43  fn as_mut(&mut self) -> &mut [u8] {
44    &mut self.0
45  }
46}
47
48/// random TinyMT state vector
49#[derive(PartialEq, Eq, Debug, Copy, Clone)]
50pub struct TinyMT64 {
51  status: [u64; 2],
52  mat1: u32,
53  mat2: u32,
54  tmat: u64,
55}
56
57impl TinyMT64 {
58  pub fn from_seed_u64(seed: u64) -> Self {
59    Self::from_seed(TinyMT64Seed::from(seed))
60  }
61}
62
63impl SeedableRng for TinyMT64 {
64  type Seed = TinyMT64Seed;
65
66  fn from_seed(seed: Self::Seed) -> Self {
67    let mut random = TinyMT64 { status: [0, 0], mat1: 0, mat2: 0, tmat: 0 };
68    tinymt64::tinymt64_init(&mut random, u64::from(seed));
69    random
70  }
71}
72
73impl RngCore for TinyMT64 {
74  fn next_u32(&mut self) -> u32 {
75    self.next_u64() as u32
76  }
77
78  fn next_u64(&mut self) -> u64 {
79    tinymt64::tinymt64_generate_uint64(self)
80  }
81
82  fn fill_bytes(&mut self, dest: &mut [u8]) {
83    let mut position = 0;
84    let mut remaining = dest.len();
85    while remaining > 0 {
86      let bytes = self.next_u64().to_le_bytes();
87      for b in bytes.iter().take(min(remaining, bytes.len())) {
88        dest[position] = *b;
89        position += 1;
90        remaining -= 1;
91      }
92    }
93  }
94
95  fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
96    self.fill_bytes(dest);
97    Ok(())
98  }
99}
100
101#[derive(Default)]
102pub struct TinyMT32Seed(pub [u8; 4]);
103
104impl From<u32> for TinyMT32Seed {
105  fn from(seed: u32) -> Self {
106    TinyMT32Seed(seed.to_le_bytes())
107  }
108}
109
110impl From<TinyMT32Seed> for u32 {
111  fn from(seed: TinyMT32Seed) -> Self {
112    u32::from_le_bytes(seed.0)
113  }
114}
115
116impl AsMut<[u8]> for TinyMT32Seed {
117  fn as_mut(&mut self) -> &mut [u8] {
118    &mut self.0
119  }
120}
121
122/// tinymt32 internal state vector and parameters
123#[derive(PartialEq, Eq, Debug, Copy, Clone)]
124pub struct TinyMT32 {
125  status: [u32; 4],
126  mat1: u32,
127  mat2: u32,
128  tmat: u32,
129}
130
131impl TinyMT32 {
132  pub fn from_seed_u32(seed: u32) -> Self {
133    Self::from_seed(TinyMT32Seed::from(seed))
134  }
135}
136
137impl SeedableRng for TinyMT32 {
138  type Seed = TinyMT32Seed;
139
140  fn from_seed(seed: Self::Seed) -> Self {
141    let mut random = TinyMT32 { status: [0, 0, 0, 0], mat1: 0, mat2: 0, tmat: 0 };
142    tinymt32::tinymt32_init(&mut random, u32::from(seed));
143    random
144  }
145}
146
147impl RngCore for TinyMT32 {
148  fn next_u32(&mut self) -> u32 {
149    tinymt32::tinymt32_generate_uint32(self)
150  }
151
152  fn next_u64(&mut self) -> u64 {
153    ((self.next_u32() as u64) << 32) | (self.next_u32() as u64)
154  }
155
156  fn fill_bytes(&mut self, dest: &mut [u8]) {
157    let mut position = 0;
158    let mut remaining = dest.len();
159    while remaining > 0 {
160      let bytes = self.next_u32().to_le_bytes();
161      for b in bytes.iter().take(min(remaining, bytes.len())) {
162        dest[position] = *b;
163        position += 1;
164        remaining -= 1;
165      }
166    }
167  }
168
169  fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
170    self.fill_bytes(dest);
171    Ok(())
172  }
173}