| Crates.io | jsrp |
| lib.rs | jsrp |
| version | 0.3.2 |
| created_at | 2025-07-08 20:25:30.021426+00 |
| updated_at | 2025-07-10 18:40:59.961003+00 |
| description | A Rust library for predicting JavaScript `Math.random()` output for Node, Chrome, Firefox, and Safari environments |
| homepage | |
| repository | https://github.com/matthewoestreich/js-randomness-predictor-rust |
| max_upload_size | |
| id | 1743509 |
| size | 76,682 |
A JavaScript Randomness Predictor
Predict JS Math.random output in Node, Chrome, Firefox, and Safari with Rust!
You can use this package programmatically, or via CLI.
To use programmatically
cargo add jsrp
To use CLI
This installs jsrp globally! You will be able to use the jsrp command system wide.
cargo install jsrp
Firefox
See here for known Firefox issues
use jsrp::FirefoxPredictor;
let mut ffp = FirefoxPredictor::new(vec![/*
4 random numbers copied from
using Math.random in Firefox.
*/]);
let next = ffp.predict_next()?;
// Run another Math.random() in
// Firefox to validate `next`.
Chrome
use jsrp::ChromePredictor;
let mut chrp = ChromePredictor::new(vec![/*
4 random numbers copied from
using Math.random in Chrome.
*/]);
let next = chrp.predict_next()?;
// Run another Math.random() in
// Chrome to validate `next`.
Node
See here for known Node issues
Node.js version (just the major version) when calling new!# You can get your current `Node.js` version
# by running the following command in your
# terminal:
node -p "process.versions.node.split('.')[0]"
#-> 24
Once you have your Node.js major version: (which we are using 24 as an example):
use jsrp::{NodePredictor, NodeJsMajorVersion};
let mut np_v24 = NodePredictor::new(
NodeJsMajorVersion::V24,
vec![/*
4 random numbers copied from
using Math.random in the specific
Node.js version you provided.
*/],
);
let next = np_v24.predict_next()?;
// Run another Math.random() in
// Node.js to validate `next`.
Make Predictions for Different Node.js Versions
If you have a sequence of random numbers that someone generated in Node.js v22.x.x (or whatever version) you can still run the predictor against them, regardless of your current Node.js version.
Just specify "that" version:
use jsrp::NodePredictor;
let mut np_vX = NodePredictor::new(
that_nodejs_major_version,
vec![/*
4 random numbers copied from
using Math.random in the specific
Node.js version you provided.
*/],
);
let next = np_vX.predict_next()?;
// Run another Math.random() in
// Node.js to validate `next`.
Safari
use jsrp::SafariPredictor;
let mut sp = SafariPredictor::new(vec![/*
4 random numbers copied from
using Math.random in Safari.
*/]);
let next = sp.predict_next()?;
// Run another Math.random() in
// Safari to validate `next`.
jsrp --help to get a full list of commands/arguments (as well as their shorthand equivalent).jsrp <environment> --help to get a full list of commands/arguments for a specific environment.--sequence should be separated by a space.--predictions was not provided).# Node - make 12 predictions
# Must provide a Node.js major version!
# Major versions must start with a "v"
jsrp node --sequence 0.1 0.2 0.3 --major-version v24 --predictions 12
jsrp node --sequence 0.1 0.2 0.3 --major-version v24
# Shorthand
jsrp node -s 0.1 0.2 0.3 -m v24 -p 12
# Firefox
jsrp firefox -s ... -p N
# Chrome
jsrp chrome -s ... -p N
# Safari
jsrp safari -s ... -p N
Validate Expected Results
If you already have the expected sequence, you can provide it via the --expected, or -x, flag. If provided, we will automatically validate our predictions.
# This actually works! Try it in the CLI
jsrp node\
--major-version v24\
--sequence 0.15825075235897956\
0.6837830031246955\
0.2352848927050296\
0.6995244175841968\
--expected 0.32903013894382993
# {
# "environment": "Node.js v24",
# "expected": [
# 0.32903013894382993
# ],
# "is_accurate": true,
# "predictions": [
# 0.32903013894382993
# ],
# "sequence": [
# 0.15825075235897956,
# 0.6837830031246955,
# 0.2352848927050296,
# 0.6995244175841968
# ]
# }
Export Results to JSON
# You can add `--export` (`-e` for short) to any command,
# which will export the results to .json.
# The file path MUST end in .json!!!
jsrp <environment> -s ... -e ./some/path/results.json
node -p "Array.from({ length: 4 }, Math.random)" to generate the initial sequence, you will have no way of verifying our predictions. Instead, you would need to enter the Node REPL (because all generated random numbers would be from the same context)
$ node from terminal, and then once in REPL > Array.from({ length: 4 }, Math.random) for initial sequence and > Array.from({ length: 10 }, Math.random) for expected results.TLDR; If number of predictions + sequence length > 64, we cannot make accurate predictions. We call this "pool exhaustion".
Why does this happen?
Math.random outputMath.random() they grab a number from this "pool" and return it to you
How we handle it
number of predictions + sequence length > 64, we will show a warning as well as truncate "number of predictions" to be within the allowed bounds.[1, 2, 3, 4] as the sequence, which has a length of 4, the max amount of predictions we can successfully make is 60 (because 64 - 4 = 60)You must disable "Instant Evaluation", otherwise your predictions may show incorrectly. Especially if you use more than one call to generate the initial sequence + expected values.
How to disable
If you do not want to disable "Instant Evaluation"
Math.random:/** Pretend this is the console */
// Output used as initial sequence.
Array.from({ length: 4 }, Math.random);
// Output used for validating predictions.
Array.from({ length: 10 }, Math.random);
/** Pretend this is the console */
// Only use one call! Manually separate numbers!
Array.from({ length: 6 }, Math.random);
[
// --------------------|
0.5654163987207667, // |
0.7409356182179403, // | --> Use "these" numbers as initial sequence
0.46136469064448193, //|
0.18124646315195891, //|
// --------------------|
0.25678544986069995, // --> Use the rest of the numbers for validation
0.5543550504255771,
];
NONE
NONE