#prng #random #mersennetwister #mt

tinymt

Rust implementation of TinyMT 64/32 - a lightweight variant of Mersenne Twister PRNG

8 stable releases

1.0.9 Jun 29, 2023
1.0.8 Mar 15, 2023
1.0.7 May 19, 2022
1.0.6 Jun 12, 2021
1.0.4 Feb 12, 2020

#153 in Algorithms

Download history 5/week @ 2023-10-19 24/week @ 2023-10-26 14/week @ 2023-11-02 5/week @ 2023-11-09 8/week @ 2023-11-16 24/week @ 2023-11-23 27/week @ 2023-11-30 19/week @ 2023-12-07 21/week @ 2023-12-14 24/week @ 2023-12-21 19/week @ 2023-12-28 15/week @ 2024-01-04 67/week @ 2024-01-11 105/week @ 2024-01-18 76/week @ 2024-01-25 23/week @ 2024-02-01

275 downloads per month

MIT license

29KB
450 lines

TinyMT

Release Build Status for Linux Test Status docs crates.io

Rust implementation of TinyMT 64/32 - a lightweight variant of Mersenne Twister PRNG.

This crate is based on the original TinyMT 1.1.1 @ 9d7ca3c161 implemented in C.

Features

TinyMT is a lightweight variant of Mersenne Twister MT19937, a widely used PRNG (pseudo-random number generator). This is useful in the case where you don't need so a long period as MT19937, but need sufficient randomness and speed with less memory.

This algorithm works with only 16B internal state space, which is much smaller than the 2,500B of MT19937. The period is 2¹²⁷-1, it's shorter than MT19937 but sufficient for practical use. The cost to generate one random number was as fast as 4ns on Intel Core i7-8550U CPU.

This crate provides the following two TinyMT implementations for both std and no_std environments.

  • TinyMT32 (32-bit version) for u32 and f32. This is also defined as RFC 8682 by IEFT.
  • TinyMT64 (64-bit version) for u64 and f64.

TinyMT32 has also been used for random numbers to control which monsters will hatch in Pokémon.

Note that neither TinyMT nor MT 19937 are cryptographically secure pseudo-random number generators. You shouldn't use them in applications where high security is required, such as the generation of private keys.

Getting Started

You'll be able to use TinyMT by simply adding the dependency to Cargo.toml of your project.

[dependencies]
rand = "0.8"
tinymt = "1.0"

By declaring tinymt crate at the beginning of the source code, you can use TinyMT64 or TinyMT32 to obtain random numbers.

extern crate tinymt;

use rand::{Rng, SeedableRng};
use tinymt::{TinyMT64, TinyMT64Seed};

fn main() {
  // from nondeterministic seed
  let mut random = TinyMT64::from_entropy();
  let rn = random.gen_range(0.0..1.0);
  println!("{}", rn);   // => nondeterministic but such that 0.3487526381670172

  // from deterministic seed (reproduction of random number sequence is possible)
  let mut random = TinyMT64::from_seed(TinyMT64Seed::from(0u64));
  let rn = random.gen_range(0.0..1.0);
  println!("{}", rn);   // => 0.5531250908497853
}

The TinyMT64 and TinyMT32 respectively implement the rand::RngCore features that are widely-used PRNG interface in Rust. Note that 64-bit operations for TinyMT32 will generate 32-bit random numbers two times at once for the compatibility of RngCore. You should use u32 or f32 random number to achieve the best performance in TinyMT32.

Lower-level API

This crate contains two modules tinymt::tinymt64 and tinymt::tinymt32 that have been migrated from the original C implementation. They might be useful if you are familiar with the original C implementation. Also, since they are independent of external libraries, it's able to avoid some conflict problems.

See the API Reference for all functions.

How to Build

The followings are typical cargo commands used to test, verify the quality of TinyMT.

cargo test
cargo clippy
cargo fmt       # or fmt -- --check

WebAssembly Support

TinyMT is fully available in Rust code targeting WebAssembly (WASM). If wasmer is set up in your environment, you can run cargo test --target wasm32-wasi. See also .cargo/config

If your target doesn't support WASI, like wasm32-unknown-unknown, the entropy-based seeding from OS isn't automatically supported. In this case, you can use TinyMT either by using an application-defined seed without using from_entropy(), or if the target supports JS such as a browser, by making getrandom() dependent on JS as follow.

[dependencies]
getrandom = { version = "0.2", features = ["js"] }

See the description of getrandom for more information.

Histories

  • 2023-06-30 (v1.0.9) Add support for WebAssembly.
  • 2023-03-15 (v1.0.8) no-std available.
  • 2022-05-19 (v1.0.7) Migrate the project to 2021 edition.
  • 2021-06-12 (v1.0.6) Upgrade rand to 0.8.

Licenses

MIT License

Copyright (c) 2023 Torao Takami

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

See Also

Dependencies

~300KB