From a2e892891547cffcb46bbc4732d6eb1cef91113a Mon Sep 17 00:00:00 2001 From: Quint Daenen Date: Fri, 19 Nov 2021 13:01:49 +0100 Subject: [PATCH] Add simple xor shifter. --- README.md | 3 +++ src/LFSR.mo | 9 ++++----- src/XorShift.mo | 27 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 src/XorShift.mo diff --git a/README.md b/README.md index d72a0c6..01d707d 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,6 @@ let (v, _) = feed.next(); // Iter let iter = LFSR.toIter(feed); ``` +## XorShift + +Reference: [prng](https://vigna.di.unimi.it/ftp/papers/xorshift.pdf). diff --git a/src/LFSR.mo b/src/LFSR.mo index 6d45e86..22babe5 100644 --- a/src/LFSR.mo +++ b/src/LFSR.mo @@ -1,5 +1,6 @@ import Array "mo:base/Array"; import Int "mo:base/Int"; +import IO "mo:io/IO"; import Iter "mo:base/Iter"; import Nat8 "mo:base/Nat8"; import Nat16 "mo:base/Nat16"; @@ -7,8 +8,6 @@ import Nat32 "mo:base/Nat32"; import Nat64 "mo:base/Nat64"; import Time "mo:base/Time"; -import IO "mo:io/IO"; - module { public type LFSR = { next() : (T, Bool); @@ -17,7 +16,7 @@ module { // An 8-bit linear feedback shift register. public class LFSR8( s : ?Nat8, // Seed. - ) { + ) : LFSR { private let seed : Nat8 = switch (s) { case (null) { nat8(Int.abs(Time.now())); }; case (? s) { s; }; @@ -39,7 +38,7 @@ module { // An 16-bit linear feedback shift register. public class LFSR16( s : ?Nat16, // Seed. - ) { + ) : LFSR { private let seed : Nat16 = switch (s) { case (null) { nat16(Int.abs(Time.now())); }; case (? s) { s; }; @@ -61,7 +60,7 @@ module { // An 32-bit linear feedback shift register. public class LFSR32( s : ?Nat32, // Seed. - ) { + ) : LFSR { private let seed : Nat32 = switch (s) { case (null) { nat32(Int.abs(Time.now())); }; case (? s) { s; }; diff --git a/src/XorShift.mo b/src/XorShift.mo new file mode 100644 index 0000000..4f98e23 --- /dev/null +++ b/src/XorShift.mo @@ -0,0 +1,27 @@ +import Int "mo:base/Int"; +import IO "mo:io/IO"; +import Nat64 "mo:base/Nat64"; +import Time "mo:base/Time"; + +module { + public type XorShift = { + next() : Nat64; + }; + + public class XorShift64( + s : ?Nat64, + ) : XorShift { + private let seed : Nat64 = switch (s) { + case (null) Nat64.fromNat(Int.abs(Time.now())); + case (? s) s; + }; + var state = seed; + + public func next() : Nat64 { + state ^= (state >> 12); + state ^= (state << 25); + state ^= (state >> 27); + state * 2685821657736338717; + }; + }; +};