Skip to main content

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples in this guide work on VillageSQL. Install Now →
MySQL’s RAND() generates pseudo-random numbers for things like shuffling query results. It isn’t cryptographically secure, which matters when you’re generating tokens, salts, or nonces. RANDOM_BYTES() fills that gap, and VillageSQL’s vsql_crypto extension adds gen_random_bytes() and gen_random_uuid() as part of a unified crypto API.

MySQL’s Random Functions

MySQL provides two built-in random functions with very different purposes: RAND() — Returns a pseudo-random float between 0 and 1. Fast and suitable for non-security applications: randomized query results, weighted sampling, random row selection. Not cryptographically secure.
RANDOM_BYTES(n) — Returns n cryptographically secure random bytes as VARBINARY. Use this for tokens, salts, nonces, and keys.

With VillageSQL: gen_random_bytes() and gen_random_uuid()

VillageSQL’s vsql_crypto extension adds gen_random_bytes() and gen_random_uuid(), which use OpenSSL’s RAND_bytes() — the same entropy source as RANDOM_BYTES().
The main reason to use these over the built-ins is consistency: when you’re already using digest(), hmac(), or encrypt() from vsql_crypto, keeping all crypto operations in one extension simplifies upgrades and auditing.

Generating test data

Random functions are useful for seeding test tables:

One-time tokens and invite codes

Choosing the Right Function

RANDOM_BYTES() and gen_random_bytes() are functionally equivalent — both return the same quality of randomness. If you’re already using vsql_crypto, use gen_random_bytes() to keep your crypto surface in one place. If you only need random bytes and nothing else, MySQL’s RANDOM_BYTES() works fine. If you need a UUID type with sortable variants (v7) and binary storage, use the vsql_uuid extension instead of gen_random_uuid(). See UUIDs in MySQL for the full comparison.

Frequently Asked Questions

Is RAND() safe for generating tokens?

No. RAND() is a pseudo-random number generator seeded from a predictable state. It’s fine for ORDER BY RAND() and similar non-security uses, but tokens generated with RAND() can in theory be predicted. Use RANDOM_BYTES() or gen_random_bytes() for anything security-sensitive.

How many bytes do I need for a secure token?

32 bytes (256 bits) is standard for session tokens and API keys. 16 bytes (128 bits) is the minimum for practical security. Use 32 to be safe.

Can I use gen_random_bytes() as a DEFAULT?

No — non-deterministic functions can’t be used in DEFAULT expressions in MySQL. Generate the value in each INSERT statement.

What’s the difference between gen_random_uuid() and UUID_V4() from vsql_uuid?

gen_random_uuid() returns a VARCHAR UUID string. UUID_V4() from the vsql_uuid extension returns a native UUID type with 16-byte binary storage. If you’re using UUIDs as primary keys, prefer UUID_V4() or UUID_V7() from vsql_uuid. Use gen_random_uuid() when you need a UUID string and don’t want to install a separate extension.

Troubleshooting

See also