Secure Token Generator — C# source
Generate cryptographically-secure random tokens in your browser. Pick the entropy size and format - hex, base32, base64, base62, or alphanumeric - and see the real strength in bits. Runs entirely client-side.
This is the C# implementation — the same logic the interactive tool runs, in a shareable, citable form.
// token-generator — cryptographically-secure random tokens in hex/base32/base64/base62/... alphabets, with unbiased symbol selection and entropy/strength estimates. C# (.NET 7+) port of src/lib/token-generator.ts — same logic as this dir's javascript.js; the full 8-entry alphabet table, custom alphabets and injectable RNG omitted for the 80-line budget (see javascript.js / python.py).
using System.Security.Cryptography;
static class TokenGenerator
{
// The fixed alphabets (subset).
static readonly Dictionary<string, string> Alphabets = new()
{
["hex"] = "0123456789abcdef",
["base32"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", // RFC 4648
["base64url"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
["base62"] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
};
// Resolve an alphabet name to its symbol string; unknown -> hex (the default).
static string ResolveAlphabet(string name) =>
Alphabets.TryGetValue(name, out var symbols) ? symbols : Alphabets["hex"];
// Characters needed to carry `bytes` bytes of entropy through `size` symbols.
static int OutputLength(double bytes, int size) =>
bytes < 1 || size < 2 ? 0 : (int)Math.Ceiling(bytes * 8 / Math.Log2(size));
// Pick alphabet[n] WITHOUT modulo bias: naive draw % size favors trailing
// symbols whenever size does not divide the draw range (base62 etc.), so
// any draw at or above the largest multiple of size fitting in 32 bits is
// rejected and redrawn. The 64-redraw cap stops a broken RNG from looping
// forever — same guard as the TS/Python reference.
static string SelectUnbiased(string alphabet, int n)
{
uint size = (uint)alphabet.Length;
uint limit = uint.MaxValue / size * size;
Span<byte> raw = stackalloc byte[4];
var chars = new char[n];
for (var i = 0; i < n; i++)
{
uint x;
var guard = 0;
do
{
RandomNumberGenerator.Fill(raw); // one secure 32-bit draw
x = BitConverter.ToUInt32(raw);
}
while (x >= limit && ++guard < 64);
chars[i] = alphabet[(int)(x % size)];
}
return new string(chars);
}
// Bucket an entropy estimate (bits) into the tool's strength tiers:
// weak <64 · fair 64-127 · strong 128-255 · very strong >=256.
static string StrengthLabel(double bits) =>
bits < 64 ? "weak" : bits < 128 ? "fair" : bits < 256 ? "strong" : "very strong";
// Demo: the island's three showcase rows — 16-byte hex, 20-byte base62,
// 32-byte base32 — each labeled with its real strength in bits.
static void Main()
{
foreach (var (name, bytes) in new[] { ("hex", 16.0), ("base62", 20.0), ("base32", 32.0) })
{
string alphabet = ResolveAlphabet(name);
string token = SelectUnbiased(alphabet, OutputLength(bytes, alphabet.Length));
double bits = token.Length * Math.Log2(alphabet.Length);
Console.WriteLine($"{name,-8} {(int)bytes} bytes -> {token} ({bits:F0} bits, {StrengthLabel(bits)})");
}
}
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →