Secure Token Generator — Ruby 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 Ruby 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. Ruby (3.x) 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).
require 'securerandom'
ALPHABETS = {
'hex' => '0123456789abcdef',
'base32' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', # RFC 4648
'base64url' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' \
'abcdefghijklmnopqrstuvwxyz0123456789-_',
'base62' => '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
}.freeze
# Resolve an alphabet name to its symbol string; unknown -> hex (the default).
def resolve_alphabet(name)
ALPHABETS.fetch(name, ALPHABETS['hex'])
end
# Characters needed to carry `bytes` bytes of entropy through `size` symbols.
def output_length(bytes, size)
return 0 if bytes < 1 || size < 2
(bytes * 8 / Math.log2(size)).ceil
end
# 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. SecureRandom.random_number(1 << 32) draws a uniform
# integer in [0, 2^32) from the OS CSPRNG.
def select_unbiased(alphabet, n)
size = alphabet.length
limit = 0xFFFFFFFF / size * size
Array.new(n) do
x = SecureRandom.random_number(1 << 32)
x = SecureRandom.random_number(1 << 32) while x >= limit
alphabet[x % size]
end.join
end
# Generate a token carrying `bytes` bytes of entropy through `alpha_name`.
def generate_token(bytes, alpha_name)
alphabet = resolve_alphabet(alpha_name)
return '' if alphabet.length < 2
select_unbiased(alphabet, output_length(bytes, alphabet.length))
end
# Bucket an entropy estimate (bits) into the tool's strength tiers:
# weak <64 · fair 64-127 · strong 128-255 · very strong >=256.
def strength_label(bits)
return 'weak' if bits < 64
return 'fair' if bits < 128
return 'strong' if bits < 256
'very strong'
end
# Demo: the island's three showcase rows — 16-byte hex, 20-byte base62,
# 32-byte base32 — each labeled with its real strength in bits.
[['hex', 16], ['base62', 20], ['base32', 32]].each do |name, bytes|
token = generate_token(bytes, name)
bits = token.length * Math.log2(resolve_alphabet(name).length)
puts format('%-8s %2d bytes -> %s (%.0f bits, %s)', name, bytes, token, bits, strength_label(bits))
end
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 →