#random #nodejs #park #miller #carta

bin+lib park-miller-carta-prng

An efficient Pseudo-Random Number Generator

3 releases

Uses old Rust 2015

0.1.3 Feb 6, 2018
0.1.1 Feb 2, 2018
0.1.0 Feb 1, 2018

#9 in #park

MIT license

100KB
971 lines

Park-Miller-Carta PRNG

(documentation in progress) This is a multi-language repository, demonstrating C-Rust-Node.js-Web interoperability/portability.

It utilizes Rust as a build system, in order to compile the original C implemetations by Robin Whittle. A faithful Rust port is also included, cross-compilable to asm.js and WebAssembly via Emscripten, for use in Node.js and browsers.

Using from browser

Add with npm i --save --only=production park-miller-carta-prng.

index.html:

<!DOCTYPE html>
<html>
<head>
  <title>Wasm</title>
</head>
<body>

<script type="text/javascript">
  var Module = {};

  var prng = {
    seed: (i) => Module.prng_new(i),
    destroy: (ptr) => Module.prng_destroy(ptr),
    getInteger: (ptr) => Module.next_unsigned_integer(ptr),
    getFloat: (ptr) => Module.next_unsigned_float(ptr)
  };

  function fetchAndInstantiate(url, importObject) {
    return fetch(url).then(response =>
      response.arrayBuffer()
    ).then(bytes =>
      WebAssembly.instantiate(bytes, importObject)
    ).then(results =>
      results.instance
    );
  }

  fetchAndInstantiate('node_modules/park-miller-carta-prng/dist/wasm/browser-standalone.wasm', {})
  .then( mod => {
    Module.prng_new = mod.exports.prng_new;
    Module.prng_destroy = mod.exports.prng_destroy;
    Module.next_unsigned_integer = mod.exports.next_unsigned_integer;
    Module.next_unsigned_float = mod.exports.next_unsigned_float;
  })
  .then( () => {
    var ptr = prng.seed(1);
    var container = document.createElement('div');
    container.textContent = `integer: ${prng.getInteger(ptr)} float: ${prng.getFloat(ptr)}`
    document.body.appendChild(container);
    prng.destroy(ptr);
  });

</script>
</body>
</html>

host the html via python2 -m SimpleHTTPServer/python3 -m http.server of your preferred method.

Using from Node.js

WebAssembly & asm.js

Add with npm i --save --only=production park-miller-carta-prng.

index.js:

let {prng, asmjs, wasm} = require("park-miller-carta-prng");
let assert = require('assert');

// use asm.js version
let generator = prng(asmjs)(1);

assert(generator.getInteger() === 16807);
generator.destroy();

// use wasm version
generator = prng(wasm)(1);

assert(generator.getInteger() === 16807);
generator.destroy();

You should always call destroy() when you are done using the generator. Available methods:

  • prng, takes either the supplied asmjs, or wasm modules, generated by emcc. Then, it must be supplied with a positive seed integer.
  • getInteger, getFloat and destroy methods, are self explanatory.

Native Addon

Clone the repository and npm run build:addon. check src/test.coffee for usage. [Todo] simple API, conditional build on npm download.

Using from Rust

Add park-miller-carta-prng to [dependencies] in Cargo.toml

main.rs:

extern crate prng;
use prng::PRNG;

fn main() {
    let mut prng = PRNG::new(1);
    let random_float = prng.next_unsigned_float();
    assert_eq!(0.000007826369, random_float);

    let random_int = prng.next_unsigned_integer();
    assert_eq!(282475249, random_int);
}

Getting Started

  1. Clone the repository: git clone https://github.com/kenOfYugen/park-miller-carta-prng
  2. Enter the directory: cd park-miller-carta-prng
  3. Build (add the --release flag for optimized builds)
  • Rust-C static/dynamic libraries: cargo b
  • asm.js library: cargo b --target asmjs-unknown-emscripten
  • wasm library: cargo b --target wasm32-unknown-emscripten
  • standalone wasm library: cargo b --target wasm32-unknown-unknown
  • Node.js: npm i && npm run build:all

Prerequisites

  • Rust, get it via rustup.
  • Node.js for running asm.js/wasm.
  • emsdk, for compilation to asm.js/wasm.

Checklist

  • Rust API
  • C API
  • Node.js asm.js/wasm via emscripten
  • Node.js native Addon
  • Browser asm.js/wasm via emscripten
  • wasm via --target wasm32-unknown-unknown

No runtime deps