Skip to content

Instantly share code, notes, and snippets.

@anzz1
Last active June 22, 2026 23:58
Show Gist options
  • Select an option

  • Save anzz1/3d4fdbf2f06729a10785eb270924a46c to your computer and use it in GitHub Desktop.

Select an option

Save anzz1/3d4fdbf2f06729a10785eb270924a46c to your computer and use it in GitHub Desktop.
prng.c
// prng.c
#include <stdint.h>
/* ********************* */
/* * XORSHIFT798 * */
/* * 16-bit * */
/* ********************* */
static uint16_t x798_s = 0;
static inline void x798_init()
{
while (!x798_s) {
x798_s = __rdtsc();
}
}
uint16_t x798_next(void)
{
x798_s ^= x798_s << 7;
x798_s ^= x798_s >> 9;
x798_s ^= x798_s << 8;
return x798_s;
}
/* ********************** */
/* * XOSHIRO128++ * */
/* * 32-bit * */
/* ********************** */
static uint32_t xs128_s[4] = { 0, 0, 0, 0 };
static inline void xs128_init()
{
if (!xs128_s[0] && !xs128_s[1] && !xs128_s[2] && !xs128_s[3]) {
uint64_t tsc = __rdtsc();
xs128_s[0] = ((uint32_t *)&tsc)[0];
xs128_s[1] = ((uint32_t *)&tsc)[1];
xs128_s[2] = xs128_s[0] ^ (uint32_t)(uintptr_t)&tsc;
xs128_s[3] = xs128_s[1] ^ (uint32_t)(uintptr_t)xs128_s;
}
}
uint32_t xs128_next(void)
{
const uint32_t result = (((xs128_s[0] + xs128_s[3]) << 7) | ((xs128_s[0] + xs128_s[3]) >> (32 - 7))) + xs128_s[0];
const uint32_t t = xs128_s[1] << 9;
xs128_s[2] ^= xs128_s[0];
xs128_s[3] ^= xs128_s[1];
xs128_s[1] ^= xs128_s[2];
xs128_s[0] ^= xs128_s[3];
xs128_s[2] ^= t;
xs128_s[3] = ((xs128_s[3] << 11) | (xs128_s[3] >> (32 - 11)));
return result;
}
/* ********************** */
/* * XOSHIRO256++ * */
/* * 64-bit * */
/* ********************** */
static uint64_t xs256_s[4] = { 0, 0, 0, 0 };
static inline void xs256_init()
{
if (!xs256_s[0] && !xs256_s[1] && !xs256_s[2] && !xs256_s[3]) {
uint64_t tsc = __rdtsc();
xs256_s[0] = tsc;
xs256_s[1] = xs256_s[0] ^ (uint64_t)(uintptr_t)&tsc;
xs256_s[2] = xs256_s[1] ^ (uint64_t)(uintptr_t)xs256_s;
xs256_s[3] = (uint64_t)(uintptr_t)&tsc ^ (uint64_t)(uintptr_t)xs256_s;
}
}
uint64_t xs256_next(void) {
const uint64_t result = (((xs256_s[0] + xs256_s[3]) << 23) | ((xs256_s[0] + xs256_s[3]) >> (64 - 23))) + xs256_s[0];
const uint64_t t = xs256_s[1] << 17;
xs256_s[2] ^= xs256_s[0];
xs256_s[3] ^= xs256_s[1];
xs256_s[1] ^= xs256_s[2];
xs256_s[0] ^= xs256_s[3];
xs256_s[2] ^= t;
xs256_s[3] = ((xs256_s[3] << 45) | (xs256_s[3] >> (64 - 45)));
return result;
}
/* ********************** */
/* * PCG32 * */
/* * 32-bit * */
/* ********************** */
static uint64_t pcg32_state = 0;
static uint64_t pcg32_inc = 0;
static uint32_t pcg32_next(void)
{
uint64_t oldstate = pcg32_state;
pcg32_state = oldstate * 6364136223846793005ULL + (pcg32_inc | 1);
uint32_t xorshifted = (uint32_t)(((oldstate >> 18u) ^ oldstate) >> 27u);
uint32_t rot = oldstate >> 59u;
return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
}
static void pcg32_init(void)
{
if (pcg32_state == 0) {
uint64_t seed = __rdtsc();
seed ^= (uint64_t)(uintptr_t)&seed;
pcg32_state = 0;
pcg32_inc = (seed << 1u) | 1u;
pcg32_next();
pcg32_state += seed;
pcg32_next();
}
}
static void
randombytes(char * const buf, const size_t size)
{
size_t i = 0;
pcg32_init();
while (i + 4 <= size) {
uint32_t r = pcg32_next();
*(uint32_t *)(buf + i) = r;
i += 4;
}
if (i < size) {
uint32_t r = pcg32_next();
for (size_t j = 0; i < size; ++i, ++j) {
buf[i] = (char)(r >> (j * 8));
}
}
}
int generate_random_int()
{
pcg32_init();
return (int)pcg32_next();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment