Guides › Preparing input files
Preparing input files for SP 800-22
Most surprising SP 800-22 results come from the file, not the generator. Here is how to write clean test data from common environments, and how NISTTEST.COM reads each format.
How files are read
| File | Read as | Use for |
|---|---|---|
.bin | Raw bytes, 8 bits each, most significant bit first | Almost everything. Smallest files. |
.txt with only 0/1 | One bit per character; spaces, tabs, newlines, commas and semicolons are ignored | Output that already exists as bit strings |
.txt with decimal digits | One single large decimal number, converted to binary | Digit expansions such as π or e |
17, 203, 9 is read as the single number 172039, not as three values. Convert lists of integers to bytes first (snippet below).Aim for 125,000 bytes (1,000,000 bits) so every test can run; the free test accepts up to 500 KB (why that size).
Linux and macOS
head -c 125000 /dev/urandom > urandom.bin
openssl rand -out openssl.bin 125000
Both make good known-random reference files. If your own generator fails a test that these pass, the problem is in your generator or capture.
Python
From a generator function
import struct
with open("rng.bin", "wb") as f:
for _ in range(31_250): # 31,250 × 4 bytes = 125,000 bytes
f.write(struct.pack(">I", my_rng_u32())) # one 32-bit output, big-endian
From a CSV or list of byte values (0–255)
text = open("bytes.csv").read().replace("\n", ",")
values = [int(v) for v in text.split(",") if v.strip()]
open("bytes.bin", "wb").write(bytes(values)) # raises if a value is outside 0–255
From a hex dump
text = open("dump.txt").read()
hex_digits = "".join(text.split()).replace("0x", "").replace(",", "")
open("dump.bin", "wb").write(bytes.fromhex(hex_digits))
From a text file of 0/1 characters
bits = "".join(ch for ch in open("bits.txt").read() if ch in "01")
bits = bits[: len(bits) // 8 * 8] # whole bytes only
open("bits.bin", "wb").write(int(bits, 2).to_bytes(len(bits) // 8, "big"))
C
#include <stdio.h>
#include <stdint.h>
int main(void) {
FILE *f = fopen("rng.bin", "wb"); /* "wb": no newline translation */
for (int i = 0; i < 125000; i++) {
uint8_t b = my_rng_byte();
fwrite(&b, 1, 1, f);
}
fclose(f);
return 0;
}
Arduino and ESP32 over serial
Send raw bytes from the board and capture them on the computer. Don't copy them out of a serial monitor: monitors drop and re-encode bytes.
// Board (ESP32 example)
void setup() { Serial.begin(921600); }
void loop() {
uint32_t r = esp_random();
Serial.write((uint8_t *)&r, 4);
}
# Computer: pip install pyserial
import serial
with serial.Serial("/dev/ttyUSB0", 921600, timeout=5) as port:
port.reset_input_buffer() # drop boot messages already received
data = port.read(125_000)
open("esp32.bin", "wb").write(data)
print(len(data), "bytes captured") # check nothing was lost
On ESP32, check Espressif's documentation for when esp_random() draws on a hardware entropy source (it depends on the radio or the bootloader random source being enabled). Testing in the wrong configuration measures a different generator.
Checklist before uploading
- File size matches what you expected to capture (no truncated serial reads).
- No header, timestamps, log lines or
0xprefixes in a.binfile. - Not the same buffer repeated, and not the same seed each run.
- Raw source and conditioned output tested separately if your design has both.
Got a clean file? Upload it and see all 15 test results on screen, free.
Run the free testNISTTEST.COM is an independent implementation of NIST SP 800-22 Rev. 1a and is not affiliated with or endorsed by the National Institute of Standards and Technology.