{"id":21206199,"url":"https://github.com/rtmigo/xrandom_dart","last_synced_at":"2026-03-14T02:35:01.475Z","repository":{"id":62458583,"uuid":"346910931","full_name":"rtmigo/xrandom_dart","owner":"rtmigo","description":"Dart library with random number generators focused on the consistency, performance and reproducibility","archived":false,"fork":false,"pushed_at":"2022-03-15T01:12:57.000Z","size":10973,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-11T10:41:14.235Z","etag":null,"topics":["algorithms","benchmarks","dart","dart-library","dart-package","deterministic","flutter","javascript","prng","pubdev","random","random-generation","random-number-generators","rng","splitmix","xorshift","xorshift-generator","xoshiro","xrandom"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/xrandom","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rtmigo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-12T02:36:26.000Z","updated_at":"2023-09-24T06:51:32.000Z","dependencies_parsed_at":"2022-11-02T00:31:54.710Z","dependency_job_id":null,"html_url":"https://github.com/rtmigo/xrandom_dart","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/rtmigo/xrandom_dart","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fxrandom_dart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fxrandom_dart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fxrandom_dart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fxrandom_dart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rtmigo","download_url":"https://codeload.github.com/rtmigo/xrandom_dart/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fxrandom_dart/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30486064,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-14T01:54:10.014Z","status":"online","status_checked_at":"2026-03-14T02:00:06.612Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithms","benchmarks","dart","dart-library","dart-package","deterministic","flutter","javascript","prng","pubdev","random","random-generation","random-number-generators","rng","splitmix","xorshift","xorshift-generator","xoshiro","xrandom"],"created_at":"2024-11-20T20:54:46.546Z","updated_at":"2026-03-14T02:35:01.457Z","avatar_url":"https://github.com/rtmigo.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Generic badge](https://img.shields.io/badge/status-it_works-ok.svg)\n[![Pub Package](https://img.shields.io/pub/v/xrandom.svg)](https://pub.dev/packages/xrandom)\n[![pub points](https://badges.bar/xrandom/pub%20points)](https://pub.dev/packages/xrandom/score)\n![Generic badge](https://img.shields.io/badge/testing_on-Win_|_Mac_|_Linux-blue.svg)\n![Generic badge](https://img.shields.io/badge/testing_on-VM_|_JS-blue.svg)\n\n\n# [xrandom](https://github.com/rtmigo/xrandom)\n\nClasses implementing all-purpose, rock-solid **random number generators**.\n\nLibrary priorities:\n- generation of identical bit-accurate numbers regardless of the platform\n- reproducibility of the random results in the future\n- high-quality randomness\n- performance\n\n----------\n\nIt has the same API as the standard\n[`Random`](https://api.dart.dev/stable/2.12.1/dart-math/Random-class.html)\n\n``` dart\nimport 'package:xrandom/xrandom.dart';\n\nfinal random = Xrandom();\n\nvar a = random.nextBool(); \nvar b = random.nextDouble();\nvar c = random.nextInt(n);\n\nvar unordered = [1, 2, 3, 4, 5]..shuffle(random);\n```\n\n# Creating the object\n\nThe library provides classes that differ in the first letter: `Xrandom`,\n`Qrandom`, `Drandom`.\n\nIf you just want a random number:\n\n``` dart\nfinal random = Xrandom();\n\nquoteOfTheDay = quotes[ random.nextInt(quotes.length) ];\n```\n\nIf you want the same numbers each time:\n\n``` dart\nfinal random = Drandom(); // D is for Dumb Determinism \n\ntest(\"no surprises ever\", () {\n    expect(random.nextInt(100), 42);\n    expect(random.nextInt(100), 17);\n    expect(random.nextInt(100), 96);\n});\n``` \n\nIf you are solving a computational problem:\n\n``` dart\nfinal random = Qrandom(); // Q is for Quantifiable Quality\n\nfeedMonteCarloSimulation(random);\n```\n\nIf you prefer a specific algorithm:\n\n``` dart\nfinal random = Splitmix64(); // see list of algorithms below\n\nfeedMonteCarloSimulation(random);\n```\n\n# Speed\n\nGenerating random numbers with AOT-compiled binary.\n\nSorted by `nextInt` **fastest  to slowest**\n(numbers show execution time)\n\n| Class                  | nextInt | nextDouble | nextBool |\n|------------------------|--------:|-----------:|---------:|\n| Xrandom                |     627 |        640 |      391 |\n| **Random (dart:math)** |     895 |        929 |      662 |\n| Qrandom / Drandom      |     933 |       1219 |      398 |\n\n\n# Additions to Random\n\n\n## nextFloat\n\n`nextFloat()` generates a floating-point value in the range 0.0 ≤ x \u003c1.0.\n\nUnlike the `nextDouble`, `nextFloat` prefers speed to precision.\nIt's still a `double`, but it has four billion shades instead of eight \nquadrillions.\n\n\u003cdetails\u003e\n  \u003csummary\u003eSpeed comparison\u003c/summary\u003e\n\nSorted by `nextDouble` **fastest  to slowest**\n(numbers show execution time)\n\n| JS | Class                  | nextDouble | nextFloat |\n|----|------------------------|-----------:|----------:|\n|    | Xorshift64             |        569 |       353 |\n|    | Xorshift128p           |        635 |       389 |\n| ✓  | Xrandom                |        640 |       221 |\n|    | Splitmix64             |        658 |       398 |\n| ✓  | Xorshift128            |        815 |       339 |\n|    | Mulberry32             |        841 |       301 |\n| ✓  | **Random (dart:math)** |        929 |           |\n|    | Xoshiro256pp           |       1182 |       713 |\n| ✓  | Qrandom / Drandom      |       1219 |       539 |\n\n\n\u003c/details\u003e\n\n\n## nextRaw\n\nThese methods return the raw output of the generator uncompromisingly fast.\nDepending on the algorithm, the output is a number consisting of either 32\nrandom bits or 64 random bits.\n\nXrandom combines small integers or splits large ones. The methods work with any\nof the generators.\n\n\n| JS    | Method        | Returns         | Equivalent of                   | \n|-------|--------|-----------------|---------------------------------|\n| ✓ | `nextRaw32()` | 32-bit unsigned | `nextInt(pow(2,32))`         |\n| ✓ | `nextRaw53()` | 53-bit unsigned | `nextInt(pow(2,53))`         |\n|   | `nextRaw64()` | 64-bit signed   | `nextInt(pow(2,64))` |\n\n\n\u003cdetails\u003e\n  \u003csummary\u003eSpeed comparison\u003c/summary\u003e\n  \nSorted by `nextInt` **fastest  to slowest**  \n(numbers show execution time)\n  \n  \n| JS | Class                  | nextInt | nextRaw32 | nextRaw64 |\n|----|------------------------|--------:|----------:|----------:|\n| ✓  | Xrandom                |     627 |       280 |       549 |\n| ✓  | Xorshift128            |     726 |       341 |       782 |\n|    | Xorshift64             |     748 |       346 |       491 |\n|    | Mulberry32             |     767 |       307 |       709 |\n|    | Xorshift128p           |     772 |       383 |       529 |\n|    | Splitmix64             |     838 |       398 |       500 |\n| ✓  | **Random (dart:math)** |     895 |           |           |\n| ✓  | XrandomHq              |     933 |       537 |      1186 |\n|    | Xoshiro256pp           |    1138 |       703 |      1072 |\n\n\nSince `nextInt`'s return range is always limited to 32 bits, \nonly comparison to `nextRaw32` is \"apples-to-apples\".\n\n\u003c/details\u003e\n\n\n\n\n\n# Algorithms\n\n| Native | JS | Class          | Algorithm                                                         |    Introduced | Alias |\n|:------:|:--:|----------------|-------------------------------------------------------------------|:-----------------:|------|\n| ✓      | ✓  | `Xorshift32`   | [xorshift32](https://www.jstatsoft.org/article/view/v008i14)      | 2003 | `Xrandom` |\n| ✓      |    | `Xorshift64`   | [xorshift64](https://www.jstatsoft.org/article/view/v008i14)      |  2003 |\n| ✓      | ✓  | `Xorshift128`  | [xorshift128](https://www.jstatsoft.org/article/view/v008i14)     |  2003 |\n| ✓      |    | `Splitmix64`   | [splitmix64](https://prng.di.unimi.it/splitmix64.c)               |  2015 |\n| ✓      |    | `Xorshift128p` | [xorshift128+ v2](https://arxiv.org/abs/1404.0390)                |  2015 |\n| ✓      |    | `Mulberry32`   | [mulberry32](https://git.io/JmoUq)                                |  2017 |\n| ✓      |    | `Xoshiro256ss` | [xoshiro256** 1.0](https://xoshiro.di.unimi.it/xoshiro256starstar.c) |  2018 |  |\n| ✓      | ✓  | `Xoshiro128pp` | [xoshiro128++ 1.0](https://prng.di.unimi.it/xoshiro128plusplus.c) |  2019 | `Qrandom`, `Drandom` |\n| ✓      |    | `Xoshiro256pp` | [xoshiro256++ 1.0](https://prng.di.unimi.it/xoshiro256plusplus.c) |  2019 |  |\n\n\nYou can use any generator from the library in the same way as in the examples with the `Xrandom` class.\n\n``` dart\nfinal random = Mulberry32();\n\nquoteOfTheDay = quotes[ random.nextInt(quotes.length) ];\n```\n\n# Compatibility\n\nTL;DR `Xrandom`, `Qrandom`, `Drandom` work on all platforms. Others may not work\non JS.\n\nThe library is written in pure Dart. Therefore, it works wherever Dart works.\n\nBut some of the classes need full support for 64-bit integers. *JavaScript**\nactually only supports **53 bits**. If your target platform is JavaScript, then\nthe selection will have to be narrowed down to the options marked with **[✓]\ncheckmark in the JS column**. Trying to create a incompatible object in\nJavaScript-transpiled code will lead to `UnsupportedError`.\n\nIf your code compiles to native (like in **Flutter** apps for **Android** and\n*iOS**), *64-bit** generators will work best for you. For example, `Xorshift64`\nfor speed or `Xoshiro256pp` for quality.\n\n# More benchmarks\n\n`nextInt` **fastest  to slowest**\n(numbers show execution time)\n\n| JS | Class                  | nextInt | nextDouble | nextBool |\n|----|------------------------|--------:|-----------:|---------:|\n| ✓  | Xrandom                |     627 |        640 |      391 |\n| ✓  | Xorshift128            |     726 |        815 |      394 |\n|    | Xorshift64             |     748 |        569 |      386 |\n|    | Mulberry32             |     767 |        841 |      391 |\n|    | Xorshift128p           |     772 |        635 |      394 |\n|    | Splitmix64             |     838 |        658 |      392 |\n| ✓  | **Random (dart:math)** |     895 |        929 |      662 |\n| ✓  | Qrandom / Drandom              |     933 |       1219 |      398 |\n|    | Xoshiro256pp           |    1138 |       1182 |      406 |\n\nAll the benchmarks on this page are from AOT-compiled binaries running on AMD \nA9-9420e with Ubuntu 20.04. Time is measured in milliseconds.\n\nThe tables are created using the [tabular](https://pub.dev/packages/tabular) \nlibrary.\n\n# Consistency\n\nThe library has been thoroughly **tested to match [reference\nnumbers](https://github.com/rtmigo/randomref)** generated by the same algorithms\nimplemented in C++. Not only `int`s, but also numbers converted to `double`\nincluding all decimal places that the compiler takes into account.\n\nThe sources in C are taken directly from scientific publications or the\nreference implementations by the authors of the algorithms. The Xorshift128+\nresults are also matched to reference values from [JavaScript xorshift\nlibrary](https://github.com/AndreasMadsen/xorshift), which tested the 128+\nsimilarly.\n\nTherefore, the sequence generated for example by the `Xoshiro128pp.nextRaw32()`\nwith the seed `(1, 2, 3, 4)` is the same as the [C99\ncode](https://prng.di.unimi.it/xoshiro128plusplus.c) will produce with the same\nseed.\n\nThe `double` values will also be the same as if the upper bits of `uint64_t`\ntype were converted to `double_t` in C99 by unsafe pointer casting. No matter\nhow exotic pointer casting sounds for Dart, and even more so for JavaScript.\nJavaScript doesn't even have any upper bits of `uint64_t`. But `double`s are the\nsame type everywhere, and their random values will be the same.\n\nTesting is done in the GitHub Actions cloud on **Windows**, **Ubuntu**, and\n**macOS** in **VM** and **Node.js** modes.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frtmigo%2Fxrandom_dart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frtmigo%2Fxrandom_dart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frtmigo%2Fxrandom_dart/lists"}