Random text generator
Blocks of random characters for overflow, truncation and fixture testing, generated in your browser.
More options
Three different things share this name
People searching for a random text generator want one of three things, and they are not close to each other. Some want a block of random characters, which is what this page produces. Some want lorem ipsum, the Latin-derived placeholder prose that designers use to fill a layout. And some want the rand function in Microsoft Word, where typing an equals sign followed by rand and a pair of brackets, then pressing Enter, inserts sample paragraphs into the document, with a lorem variant that inserts Latin instead.
This page serves the first of those and does not attempt the other two. There is no lorem ipsum here, no sentence structure, no word list and no paragraph shaping. What you get is a run of characters drawn uniformly from whichever alphabet you select.
That is a deliberate boundary rather than an omission. Placeholder prose and random characters are different tools that fail differently, and a page that pretended to do both would do neither well.
Random characters are not placeholder text
Lorem ipsum works because it imitates the statistics of real language. It has word lengths that vary the way words vary, spaces roughly every five or six characters, sentences that end, and a rhythm that lets a line of type break the way a real line of type will break. Set a paragraph in it and you can judge measure, leading and colour on the page.
A uniform character string has none of that. Every character is equally likely, there are no spaces unless you add them, and a 200-character run is a single unbreakable word. Drop it into a paragraph and it will not wrap at all, which tells you nothing about your typography.
What it tells you instead is whether your layout survives content that refuses to cooperate, and that is a genuinely useful and completely different test. An unbroken 200-character string is the fastest way to find a container that does not clip, a table cell with no overflow rule, a flex item with no min-width, or a truncation that was never implemented. Use lorem ipsum to see whether a design reads. Use this to see whether it breaks.
What a random character block is actually good for
Overflow and truncation testing is the main one, for the reason above. Beyond that, random character blocks are the standard filler for database fixtures where a text column needs realistic length but no meaning, for exercising input length limits and validation boundaries, for filling a field to exactly the maximum a schema allows so you can check the off-by-one, and for cache-busting values in a URL where the content does not matter.
They are also the right choice when meaningful placeholder text would be actively misleading. Screenshots of a product with lorem ipsum in them get mistaken for real copy and end up in a slide deck; a block of random characters never does.
Where they are the wrong choice is anywhere a human has to read, type, dictate or remember the value. For that you want words, and a passphrase drawn from a word list is the tool.
The entropy of a text block, if you need the number
Uniform characters make the arithmetic exact. Lowercase letters give log2(26) = 4.70044 bits per character, so a 200-character lowercase block carries 940.09 bits. Adding uppercase gives exactly one more bit per character, because log2(52) is precisely log2(26) plus one. Alphanumeric at 62 symbols gives 5.9542 bits per character.
Those figures are only correct because the characters are independent and uniform. They stop being correct the moment you impose a constraint such as requiring at least one digit, because that breaks independence, and the true value is then the log of the number of valid strings rather than the length times the bits per character. This tool computes the corrected figure rather than the naive one.
For a block used as test data the number is beside the point. It is worth knowing anyway, because a text block is occasionally pressed into service as a secret, and at that moment the exact figure is the only thing that matters.
Testing with characters your users will actually send
A block of lowercase ASCII is a weak test of anything that handles text, because ASCII is the case every implementation already gets right. The interesting failures live outside it, and a serious test corpus should include them deliberately rather than hoping randomness finds them.
The specific trap in JavaScript is that strings are sequences of UTF-16 code units rather than characters. Any code point above U+FFFF occupies two of them, so a single emoji has a length of 2, slicing a string can split a surrogate pair and produce an invalid fragment, and a length check measured in code units does not measure what a user would call characters. Combining marks add a second layer, where a visible character can be several code points and normalisation changes the length without changing the meaning. Right-to-left text adds a third, where the visual order and the logical order differ.
Random ASCII will never surface any of that. Generate the block here for the overflow case, and keep a fixed handful of deliberately awkward strings alongside it for the encoding case.
Doing this in your own code
JavaScript (browser and Node 19+)
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
function randomString(length) {
const n = ALPHABET.length;
// Largest multiple of n that fits in a uint32. Values at or above this
// are discarded, which is what removes the modulo bias.
const limit = Math.floor(2 ** 32 / n) * n;
const out = new Array(length);
const buf = new Uint32Array(length);
crypto.getRandomValues(buf);
for (let i = 0, j = 0; i < length; i++) {
let v = buf[j++];
while (v >= limit) {
// Refill one word at a time on the rare rejection.
const extra = new Uint32Array(1);
crypto.getRandomValues(extra);
v = extra[0];
}
out[i] = ALPHABET[v % n];
}
return out.join("");
}
randomString(24); crypto.getRandomValues() refuses a single request over 65536 bytes, so a large batch has to be chunked.
Python 3.6+
import secrets
import string
ALPHABET = string.ascii_letters + string.digits
def random_string(length: int) -> str:
# secrets.choice() is unbiased: it uses randbelow(), which is itself
# rejection sampling over os.urandom. Do not use random.choice() here,
# which is a Mersenne Twister and is not cryptographically secure.
return "".join(secrets.choice(ALPHABET) for _ in range(length))
random_string(24) secrets has been in the standard library since 3.6. Anything using the random module is the wrong tool for a secret.
Go
package main
import (
"crypto/rand"
"math/big"
)
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
func randomString(length int) (string, error) {
out := make([]byte, length)
max := big.NewInt(int64(len(alphabet)))
for i := range out {
// rand.Int is unbiased; it rejects internally.
n, err := rand.Int(rand.Reader, max)
if err != nil {
return "", err
}
out[i] = alphabet[n.Int64()]
}
return string(out), nil
} crypto/rand, never math/rand. Go 1.20 seeds the math/rand global generator randomly on its own, which improves nothing about its predictability.
Rust
// rand = "0.9"
use rand::Rng;
use rand::distr::{Alphanumeric, SampleString};
fn random_string(length: usize) -> String {
// rand::rng() is a thread-local ChaCha12 CSPRNG, seeded from the
// operating system and reseeded periodically.
// Alphanumeric samples uniformly over A-Z a-z 0-9.
Alphanumeric.sample_string(&mut rand::rng(), length)
}
// With an arbitrary alphabet, random_range rejection-samples:
fn random_from(alphabet: &[u8], length: usize) -> String {
let mut rng = rand::rng();
(0..length)
.map(|_| alphabet[rng.random_range(0..alphabet.len())] as char)
.collect()
} On rand 0.8 the paths differ: rand::distributions instead of rand::distr, DistString instead of SampleString, gen_range instead of random_range, and rand::thread_rng() instead of rand::rng().
PHP 7+
<?php
function randomString(int $length): string {
$alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$n = strlen($alphabet);
$out = '';
for ($i = 0; $i < $length; $i++) {
// random_int() is unbiased and cryptographically secure.
// rand() and mt_rand() are neither.
$out .= $alphabet[random_int(0, $n - 1)];
}
return $out;
}
echo randomString(24); Java 17+
import java.security.SecureRandom;
public final class RandomString {
private static final String ALPHABET =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static final SecureRandom RANDOM = new SecureRandom();
public static String generate(int length) {
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
// nextInt(bound) rejects internally, so it is unbiased.
sb.append(ALPHABET.charAt(RANDOM.nextInt(ALPHABET.length())));
}
return sb.toString();
}
} SecureRandom, not java.util.Random and not Math.random(), both of which are 48-bit linear congruential generators.
C# / .NET 6+
using System.Security.Cryptography;
public static class RandomStringGenerator
{
private const string Alphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
public static string Generate(int length)
{
// GetString was added in .NET 8 and is unbiased.
return RandomNumberGenerator.GetString(Alphabet, length);
}
// On .NET 6 and 7, GetInt32 is the unbiased primitive:
public static string GenerateLegacy(int length)
{
var chars = new char[length];
for (int i = 0; i < length; i++)
chars[i] = Alphabet[RandomNumberGenerator.GetInt32(Alphabet.Length)];
return new string(chars);
}
} C++11 and later
#include <random>
#include <string>
std::string random_string(std::size_t length) {
static const std::string alphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
// uniform_int_distribution is specified to give every value in the range
// equal probability, so there is no modulo bias to remove by hand.
std::random_device rd;
std::uniform_int_distribution<std::size_t> pick(0, alphabet.size() - 1);
std::string out;
out.reserve(length);
for (std::size_t i = 0; i < length; ++i) {
out += alphabet[pick(rd)];
}
return out;
} std::random_device reads the operating system source on libstdc++, libc++ and MSVC, but the standard allows it to be deterministic, and MinGW builds before GCC 9.2 were. Where a guarantee matters, use libsodium randombytes_uniform() instead. Never std::rand() or std::mt19937 for a secret.
PowerShell 7
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
# GetInt32 draws from the OS CSPRNG and rejection samples internally.
-join (1..24 | ForEach-Object {
$chars[[System.Security.Cryptography.RandomNumberGenerator]::GetInt32($chars.Length)]
}) Windows PowerShell 5.1 runs on .NET Framework, which has no GetInt32. There, pick each character with Get-Random -Maximum $chars.Length, which draws from the system CSPRNG unless -SetSeed is given. Avoid Get-Random -Count, which never repeats a character.
Shell
# 24 alphanumeric characters from the kernel CSPRNG.
LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 24; echo
# Base64, URL-safe, from 32 bytes of entropy.
openssl rand -base64 32 | tr '+/' '-_' | tr -d '=' tr discards bytes outside the set rather than folding them into it, so this pipeline is unbiased. Putting `head -c 24` before `tr` instead gives you the alphanumeric subset of 24 raw bytes, which is a shorter and variable-length string, not 24 characters.
Questions
Does this generate lorem ipsum?
No. It generates random characters. Lorem ipsum is Latin-derived placeholder prose with word and sentence structure, which is a different tool for a different job. This page has no word list.
What is the rand function people mention with random text?
It is a Microsoft Word feature. Typing an equals sign followed by rand and a pair of brackets, then pressing Enter, inserts sample paragraphs into the document. The lorem variant inserts Latin instead. It is a Word feature and has no web equivalent.
Why is the output one long unbroken run with no spaces?
Because spaces are not in the selected alphabet. That is usually what you want for an overflow test, since an unbreakable string is precisely what finds a container with no wrapping or truncation rule. If you want spaces, add them to the character set.
Can I use a block of this as a password?
You can, and the entropy figure shown is exact, but it is the wrong shape for one. A password is typed, read aloud and stored in a manager, so length past about 20 characters is pure friction with no security benefit.
Is this good test data for a database?
For length, yes. For anything that depends on the content, no. If you are testing search, sorting, collation or display, you need text that resembles the real thing, and random characters will make every one of those tests pass for the wrong reason.