Implement MT19937 for challenge 21.
This commit is contained in:
@@ -3,6 +3,7 @@ mod bytes_base64;
|
|||||||
mod cbc;
|
mod cbc;
|
||||||
mod ctr;
|
mod ctr;
|
||||||
mod ecb;
|
mod ecb;
|
||||||
|
mod mt19937;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod set1;
|
mod set1;
|
||||||
mod set2;
|
mod set2;
|
||||||
@@ -32,7 +33,8 @@ fn main() {
|
|||||||
set3::challenge19();
|
set3::challenge19();
|
||||||
set3::challenge20();
|
set3::challenge20();
|
||||||
set3::challenge21();
|
set3::challenge21();
|
||||||
|
set3::challenge22();
|
||||||
} else {
|
} else {
|
||||||
set3::challenge21();
|
set3::challenge22();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
80
src/mt19937.rs
Normal file
80
src/mt19937.rs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
use std::num::Wrapping;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MT19937 {
|
||||||
|
mt: Vec<u32>,
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
const N: usize = 624;
|
||||||
|
|
||||||
|
impl MT19937 {
|
||||||
|
pub fn new() -> MT19937 {
|
||||||
|
let mut mt = MT19937 {
|
||||||
|
mt: vec![0; N],
|
||||||
|
index: N + 1,
|
||||||
|
};
|
||||||
|
mt.seed(5489);
|
||||||
|
mt
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn seed(&mut self, seed: u32) {
|
||||||
|
self.index = N;
|
||||||
|
const F: u32 = 1812433253;
|
||||||
|
self.mt[0] = seed;
|
||||||
|
for i in 1..N {
|
||||||
|
self.mt[i] = (Wrapping(F) * Wrapping(self.mt[i - 1] ^ (self.mt[i - 1] >> 30))
|
||||||
|
+ Wrapping(i as u32))
|
||||||
|
.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extract_number(&mut self) -> u32 {
|
||||||
|
if self.index >= N {
|
||||||
|
if self.index > N {
|
||||||
|
panic!("Generator was never seeded");
|
||||||
|
}
|
||||||
|
self.twist();
|
||||||
|
}
|
||||||
|
|
||||||
|
const S: u32 = 7;
|
||||||
|
const T: u32 = 15;
|
||||||
|
const U: u32 = 11;
|
||||||
|
const B: u32 = 0x9D2C5680;
|
||||||
|
const C: u32 = 0xEFC60000;
|
||||||
|
const D: u32 = 0xFFFFFFFF;
|
||||||
|
const L: u32 = 18;
|
||||||
|
|
||||||
|
let mut y = self.mt[self.index];
|
||||||
|
y = y ^ ((y >> U) & D);
|
||||||
|
y = y ^ ((y << S) & B);
|
||||||
|
y = y ^ ((y << T) & C);
|
||||||
|
y = y ^ (y >> L);
|
||||||
|
self.index += 1;
|
||||||
|
y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn twist(&mut self) {
|
||||||
|
const M: usize = 397;
|
||||||
|
const R: u32 = 31;
|
||||||
|
const A: u32 = 0x9908B0DF;
|
||||||
|
const LOWER_MASK: u32 = (1 << R) - 1; // 0x7fffffff
|
||||||
|
const UPPER_MASK: u32 = !LOWER_MASK; // 0x80000000
|
||||||
|
const FIRST_HALF: usize = N - M;
|
||||||
|
|
||||||
|
for i in 0..FIRST_HALF {
|
||||||
|
let bits = self.mt[i] & UPPER_MASK | self.mt[i + 1] & LOWER_MASK;
|
||||||
|
self.mt[i] = self.mt[i + M] ^ (bits >> 1) ^ ((bits & 1) * A);
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in FIRST_HALF..(N - 1) {
|
||||||
|
let bits = self.mt[i] & UPPER_MASK | self.mt[i + 1] & LOWER_MASK;
|
||||||
|
self.mt[i] = self.mt[i - FIRST_HALF] ^ (bits >> 1) ^ ((bits & 1) * A);
|
||||||
|
}
|
||||||
|
|
||||||
|
let i = N - 1;
|
||||||
|
let bits = self.mt[i] & UPPER_MASK | self.mt[0] & LOWER_MASK;
|
||||||
|
self.mt[i] = self.mt[M - 1] ^ (bits >> 1) ^ ((bits & 1) * A);
|
||||||
|
self.index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/set3.rs
18
src/set3.rs
@@ -2,6 +2,7 @@ use crate::bytes::Bytes;
|
|||||||
use crate::bytes_base64::BytesBase64;
|
use crate::bytes_base64::BytesBase64;
|
||||||
use crate::cbc;
|
use crate::cbc;
|
||||||
use crate::ctr;
|
use crate::ctr;
|
||||||
|
use crate::mt19937;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@@ -301,5 +302,20 @@ pub fn challenge20() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn challenge21() {
|
pub fn challenge21() {
|
||||||
println!("[xxxx] Challenge 21: TBD");
|
// Implement the MT19937 Mersenne Twister RNG
|
||||||
|
|
||||||
|
let expected: Vec<u32> = vec![
|
||||||
|
0xD091BB5C, 0x22AE9EF6, 0xE7E1FAEE, 0xD5C31F79, 0x2082352C, 0xF807B7DF, 0xE9D30005,
|
||||||
|
0x3895AFE1, 0xA1E24BBA, 0x4EE4092B,
|
||||||
|
];
|
||||||
|
let mut mt = mt19937::MT19937::new();
|
||||||
|
mt.seed(5489);
|
||||||
|
for i in 0..expected.len() {
|
||||||
|
assert_eq!(mt.extract_number(), expected[i]);
|
||||||
|
}
|
||||||
|
println!("[okay] Challenge 21: Implemented MT19937");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn challenge22() {
|
||||||
|
println!("[xxxx] Challenge 22: TBD!");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user