commit 850eea5bc56c79011285ec9d38908aa234f18259 Author: hellerve Date: Sat Sep 2 16:27:08 2017 +0200 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4308d82 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +target/ +**/*.rs.bk +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..3127eeb --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "permute" +version = "0.1.0" +authors = ["hellerve "] + +[dependencies] diff --git a/README.md b/README.md new file mode 100644 index 0000000..a8a4d85 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# permute + +A Rust implementation of the unique random integer generation described +[here](http://preshing.com/20121224/how-to-generate-a-sequence-of-unique-random-integers/). diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..e1f6c3a --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,32 @@ +pub struct RandomSeq { + idx: u32, + offs: u32, +} + + +fn permute_qpr(i: u32) -> u32 { + let x = i as u64; + let prime = 4294967291; + if x >= prime { return x as u32; } + + let residue = (x * x) % prime; + if x <= prime / 2 { + return residue as u32; + } + return (prime - residue) as u32; +} + +impl RandomSeq { + pub fn new(base: u32, offset: u32) -> RandomSeq { + RandomSeq { + idx: permute_qpr(permute_qpr(base) + 0x682f0161), + offs: permute_qpr(permute_qpr(offset) + 0x46790905), + } + } + + pub fn next(&mut self) -> u32 { + let res = permute_qpr((permute_qpr(self.idx) + self.offs) ^ 0x5bf03635); + self.idx += 1; + return res; + } +}