RandN 0.2.0

.NET 5.0 .NET Core 3.1 .NET Standard 2.0
There is a newer version of this package available.
See the version list below for details.
Install-Package RandN -Version 0.2.0
dotnet add package RandN --version 0.2.0
<PackageReference Include="RandN" Version="0.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add RandN --version 0.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: RandN, 0.2.0"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install RandN as a Cake Addin
#addin nuget:?package=RandN&version=0.2.0

// Install RandN as a Cake Tool
#tool nuget:?package=RandN&version=0.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.


RandN on NuGet

RandN is a .NET library for random number generation. It aims to rectify deficiencies in System.Random with adaptability and extensibility in mind. RandN is heavily inspired by the design of the Rust crate rand, and aims to maintain some level of compatibility with it.

What's wrong with System.Random?

In short, the algorithm it uses is slow and biased. The API is very rigid and inflexible, and as a result is unsuited for many purposes.

RandN provides a clear and obvious API that is difficult to use incorrectly, unlike the API of System.Random. This is accomplished by clearly separating two concepts; generating randomness with an IRng, and turning that data into something useful with an IDistribution.


he full documentation is available here.


Install the RandN package from NuGet for most use cases. If you just want to implement an random number generator (ex. you're publishing a package with a new RNG), instead depend on RandN.Core.


Creating an RNG

using RandN;

// Creates a cryptographically secure RNG
var rng = StandardRng.Create();

// Creates a non-cryptographically secure RNG that's fast and uses less memory
var insecureRng = SmallRng.Create();

A reproducible RNG can also be created by using an algorithm directly:

using RandN.Rngs;

// Use ThreadLocalRng to seed the RNG - this uses a cryptographically secure
// algorithm, so tight loops won't result in similar seeds
var seeder = ThreadLocalRng.Instance;

// Create the seed (Seeds can also be created manually)
var factory = ChaCha.GetChaCha8Factory();
var seed = factory.CreateSeed(seeder);

// Create the RNG from the seed
var rng = factory.Create(seed);

Getting random numbers

Once you have an RNG, you can either use it directly,

var num = rng.NextUInt32();
var bigNum = rng.NextUInt64();
var buffer = new Byte[1000];

or you can use it to sample a distribution:

Uniform.Int32 distribution = Uniform.NewInclusive(42, 54); // [42 - 54]
int answer = distribution.Sample(rng);

Bernoulli weightedCoin = Bernoulli.FromRatio(8, 10); // 80% chance of true
bool probablyHeads = weightedCoin.Sample(rng);

Shuffling a list is also easy:

var list = new List<Int32>() { 1, 2, 3, 4, 5, 6 };

Any type implementing IRng can be wrapped with RandomShim, which can be used as a drop-in replacement for Random.

using RandN.Compat;
Random random = RandomShim.Create(rng);
random.Next(2); // returns 0 or 1
Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows
.NET Core netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard2.0 netstandard2.1
.NET Framework net461 net462 net463 net47 net471 net472 net48
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.3.0 9,719 6/20/2021
0.2.0 7,011 12/21/2020
0.1.0 4,096 6/20/2020

Version 0.2.0

     New APIs:
     The marker-interface IPortableDistribution has been created to mark distributions that provide portable and repeatable results across all platforms. Currently, the Bernoulli, the uniform Decimal, the uniform TimeSpan, and all the uniform integer distributions are portable.
     Added BlockBuffer32<TBlockRng, TBlockCounter>.BlockLength for consistency with BlockBuffer32.BlockLength.

     Updated APIs:
     Uniform distributions now live have been grouped into nested classes under the Uniform static class. For example, UniformInt32 has become Uniform.Int32.
     Unit interval distributions now live in the Rand.Distributions.UnitInterval namespace and have been grouped into nested classes. For example, UnitInterval.OpenDouble has become UnitInterval.Open.Double.
     Method arguments now have null-checks injected by NullGuard.Fody instead of relying on the honor system.
     The TRng type parameter of IRngFactory and IReproducibleRngFactory<TRng, TSeed> is now covariant (IRngFactory<out TRng>).
     BlockBuffer32<TBlockRng>.Length has been renamed to BlockLength.

     Removed APIs:
     Removed the Sample extension methods - these were questionably useful, and could be up to four times slower than their non-extension counterpart, IDistribution.Sample.

     Bug fixes:
     Distributions returning floating point numbers would sometimes sample a number outside the desired range on .NET Framework x86, which can use 80-bit floating point calculations, instead of 64-bit. Results are now forced to 64-bit precision before returning.
     BitwiseExtensions.RotateRight now rotates bits right instead of left on .NET Core 3.1+.
     All places where overflow is expected is now marked with unchecked.