gengo is a zero-dependency Go library for generating random test data — strings, numbers, dates, booleans, and words — with a single function call. No configuration, no boilerplate. Just fast, reliable random data whenever you need it.
Generating realistic test data in Go usually means writing repetitive helper functions or pulling in heavy dependencies. gengo solves this with a clean, idiomatic API that covers the most common use cases out of the box:
- One function call to generate any random value
- Zero external dependencies — only the Go standard library
- Blazing fast — single-digit-nanosecond generation for primitive types on modern hardware
- Safe by default — built-in overflow protection, size limits, and uniform distribution
go get -u github.com/FlavioCFOliveira/gengoRequires Go 1.26 or later.
package main
import (
"fmt"
"github.com/FlavioCFOliveira/gengo"
)
func main() {
// Random alphanumeric string — handy for test fixtures and IDs
fmt.Println(gengo.StringAlphanumeric(20))
// Output: k9mP2vLxQr5tWnB8aJcT
// Random integer in a custom range
fmt.Println(gengo.IntBetween(1, 100))
// Output: 42
// Random date anywhere in history or the future
fmt.Println(gengo.Date())
// Output: 1847-03-15 08:23:17 UTC
}- String Generation
- Number Generation
- Date & Time
- Booleans
- Words & Text
- Reproducible Output
- Character Sets
- Safety & Limits
- Performance
All string functions accept a length parameter — the number of bytes, capped at 1 MB. Pick a predefined type or pass your own character set. String generation is byte-oriented, so custom character sets should contain only single-byte (ASCII) characters; multibyte input (emoji, accents, CJK) produces invalid UTF-8.
// Generate from a custom character set
custom := gengo.String(10, "ABC123")
// Output: C1BA3C2A1B
// Generate a string with a random length between min and max
variable := gengo.StringBetween(5, 15, gengo.Alphanumeric)| Function | Output characters | Example |
|---|---|---|
StringAllChars(n) |
Letters + numbers + symbols | aB3$kP9@mQ |
StringAlphanumeric(n) |
Letters + numbers | xK8pM2vLqR |
StringAlphabetic(n) |
Upper and lower case letters | bGtRvNmKlP |
StringAlphabeticUppercase(n) |
A–Z only | XKMTPQRLVN |
StringAlphabeticLowercase(n) |
a–z only | mkptqrvbgs |
StringNumeric(n) |
Digits 0–9 only | 8472936105 |
StringHexadecimal(n) |
Hex digits 0–9, A–F | A7F3B9E2D1 |
StringSymbols(n) |
Special characters only | @#$%&*()-_ |
Warning
gengo is not cryptographically secure. It is built on
math/rand/v2, whose output is fast but
predictable and therefore unsuitable for any security-sensitive purpose.
Never use gengo to generate passwords, API tokens, session IDs,
encryption keys, salts, or any other secret — the results are guessable. For
secrets, use Go's crypto/rand package
instead.
See SECURITY.md for the full security policy and how to report a vulnerability.
// Short, human-readable identifier for test fixtures
id := gengo.StringAlphanumeric(8)
// Output: xK8pM2vL
// Random label for seeding a database column
label := gengo.StringAlphabetic(12)
// Output: bGtRvNmKlPqX
// Random hex value for non-secret test data (e.g. a fake colour code)
hex := gengo.StringHexadecimal(6)
// Output: A7F3B9Every integer type comes in two flavours:
Type()— full range of that typeTypeBetween(min, max)— your custom range (min and max are swapped automatically if reversed)
| Type | Function | Full Range | Range example |
|---|---|---|---|
int8 |
Int8() |
−128 to 127 | Int8Between(-50, 50) |
int16 |
Int16() |
−32 768 to 32 767 | Int16Between(100, 1000) |
int32 |
Int32() |
±2 billion | Int32Between(0, 999999) |
int64 |
Int64() |
±9 quintillion | Int64Between(0, time.Now().Unix()) |
int |
Int() |
Platform dependent | IntBetween(1, 100) |
uint8 / byte |
Uint8() / Byte() |
0 to 255 | Uint8Between(0, 255) |
uint16 |
Uint16() |
0 to 65 535 | Uint16Between(1000, 5000) |
uint32 |
Uint32() |
0 to 4 billion | Uint32Between(0, 100000) |
uint64 |
Uint64() |
0 to 18 quintillion | Uint64Between(0, math.MaxUint32) |
// Random age between 18 and 100
age := gengo.IntBetween(18, 100)
// Random percentage (0–100)
percent := gengo.Uint8Between(0, 100)
// Random unprivileged port number
port := gengo.Uint16Between(1024, 65535)
// Random byte for binary data
b := gengo.Byte()| Function | Range | Description |
|---|---|---|
Float32() |
(0, MaxFloat32) | Positive values only — use Float32Between for negatives or a custom range |
Float32Between(min, max) |
Custom | Bounded float32 |
Float64() |
(0, MaxFloat64) | Positive values only — use Float64Between for negatives or a custom range |
Float64Between(min, max) |
Custom | Bounded float64 |
// Random price for e-commerce testing
price := gengo.Float64Between(0.99, 999.99)
// Random percentage with decimal precision
percentage := gengo.Float32Between(0.0, 100.0)
// Random geographic coordinates
lat := gengo.Float64Between(-90.0, 90.0)
lng := gengo.Float64Between(-180.0, 180.0)| Function | Description |
|---|---|
Complex64() |
Random complex64 with random real and imaginary parts |
Complex64Between(rMin, rMax, iMin, iMax) |
Custom ranges for both parts |
Complex128() |
Random complex128 with random real and imaginary parts |
Complex128Between(rMin, rMax, iMin, iMax) |
Custom ranges for both parts |
// Random complex number
c := gengo.Complex64()
// Output: (12.34+56.78i)
// Bounded unit circle range
c = gengo.Complex64Between(-1.0, 1.0, -1.0, 1.0)
// Output: (0.45-0.92i)Generate random timestamps for testing date-sensitive logic, filling databases with realistic data, or simulating time-based events.
| Function | Description | Range |
|---|---|---|
Date() |
Random date and time | Year 1 to 9999 |
UnixDate() |
Random Unix timestamp | 1970 to 2038 (32-bit range) |
DateBetween(start, end) |
Random date within a specific range | Custom |
All date functions work at whole-second granularity and return UTC times with a zero sub-second component. For
DateBetween, the bounds' sub-second parts are ignored; as a special case, whenstartandendfall within the same second,startis returned unchanged.
// Random historical or future date
d := gengo.Date()
// Output: 1847-03-15 08:23:17 UTC
// Random date in the Unix epoch range
d = gengo.UnixDate()
// Output: 1995-11-30 14:45:02 UTC
// Random date within a custom range
start := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
end := time.Date(2024, 12, 31, 0, 0, 0, 0, time.UTC)
d = gengo.DateBetween(start, end)
// Output: 2022-07-14 09:33:45 UTC
// Random birthdate for someone aged 18 to 65
now := time.Now()
minAge := now.AddDate(-65, 0, 0)
maxAge := now.AddDate(-18, 0, 0)
birthdate := gengo.DateBetween(minAge, maxAge)// 50/50 coin flip
if gengo.Bool() {
fmt.Println("Heads")
} else {
fmt.Println("Tails")
}
// Randomly toggle a feature flag in tests
if gengo.Bool() {
enableNewFeature()
}Generate random words for populating text fields, testing search functionality, or seeding databases with human-readable content.
// Random word between 2 and 30 lowercase letters
word := gengo.Word()
// Output: galhjhyqxfmvwqxqywuigohxhvclk| Category | Length | Example output |
|---|---|---|
SmallLengthWord |
1–4 chars | cat, dog, sun |
MediumLengthWords |
5–8 chars | house, garden |
BigLengthWords |
9–30 chars | wonderful, beautiful |
small := gengo.WordByLengthType(gengo.SmallLengthWord)
medium := gengo.WordByLengthType(gengo.MediumLengthWords)
big := gengo.WordByLengthType(gengo.BigLengthWords)// Generate a slice of random words
words := gengo.Words(5)
// Output: [ok then computer building wonderful]
// Natural-language-like distribution (from WordLengthRatio, 13/26/11 of 50):
// ~26% small words (1–4 chars)
// ~52% medium words (5–8 chars)
// ~22% big words (9–30 chars)By default, gengo's package-level functions draw from Go's global math/rand/v2 source, which is automatically seeded — great for variety, but the output cannot be reproduced. When you need a deterministic sequence (for example, to reproduce a failing test), create a seeded Generator:
// Same seed → same sequence, every run
g := gengo.New(42)
fmt.Println(g.IntBetween(1, 100)) // deterministic for seed 42
fmt.Println(g.String(8, gengo.Alphanumeric)) // deterministic for seed 42
// A second generator with the same seed reproduces the sequence exactly
g2 := gengo.New(42)
// g2 yields the identical sequence as gA Generator exposes a method for every package-level function (g.Int8(), g.Float64Between(...), g.Date(), g.Word(), and so on), so it is a drop-in replacement when you need reproducibility. For full control over the underlying algorithm, build one from any math/rand/v2 source:
import "math/rand/v2"
g := gengo.NewSource(rand.NewPCG(1, 2))A
Generatoris not safe for concurrent use by multiple goroutines (it wraps amath/rand/v2.Rand). Use one generator per goroutine, or the package-level functions — which are safe for concurrent use — when you don't need reproducibility.
Use these built-in constants to build your own character sets or combine them for custom string generation.
| Constant | Characters | Size |
|---|---|---|
AllChars |
a-zA-Z0-9!@#$%... |
87 |
Alphanumeric |
a-zA-Z0-9 |
62 |
Alphabetic |
a-zA-Z |
52 |
AlphabeticUppercase |
A-Z |
26 |
AlphabeticLowercase |
a-z |
26 |
Numeric |
0-9 |
10 |
Hexadecimal |
0-9A-F |
16 |
Symbols |
!@#$%... |
25 |
// Letters and underscores — safe for usernames
usernameSafe := gengo.AlphabeticLowercase + "_"
name := gengo.String(12, usernameSafe)
// URL-safe slugs
urlSafe := gengo.Alphanumeric + "-_"
slug := gengo.String(20, urlSafe)
// Fun custom charset (ASCII) — e.g. DNA bases
dna := "ACGT"
sequence := gengo.String(20, dna)
// Output: GATTACAGATTACAGGCTAGgengo is designed to be safe to use in production code and CI pipelines without any extra configuration:
- String length cap: Maximum 1 MB (
MaxStringLength) prevents accidental memory exhaustion - Automatic range correction: All
Betweenfunctions swap min and max if they are reversed - Overflow protection: Integer calculations use wider intermediate types to prevent wrap-around
- Uniform distribution: Backed by
math/rand/v2for statistically unbiased results
Benchmarks run on an AMD Ryzen 9 5900HX (Go 1.26.2, -benchtime 5s). See make bench to reproduce on your machine.
| Operation | ns/op |
|---|---|
IntBetween |
~7.8 |
Float64 |
~5.8 |
String (8 chars) |
~27.8 |
Date |
~7.4 |
Uint64 |
~4.8 |
For the full benchmark report and detailed test results, see BENCHMARKS.md and TEST_REPORT.md.
Contributions are welcome! See CONTRIBUTING.md for the build, test, and lint workflow, the coding conventions, and the pull-request process. For security issues, follow SECURITY.md.
Released under the MIT License.
