Eightomic iconEightomic

PRNG C 64

It's a fast, statistically-strong PRNG with 64-bit integers and a period of 2⁶⁶ to 2¹²⁸.

Algorithm

Source

#include <stdint.h> struct eightomic_prng_c_64_s { uint64_t a; uint64_t b; uint64_t c; }; uint64_t eightomic_prng_c_64(struct eightomic_prng_c_64_s *s) { uint64_t block = s->a + s->c; s->a = ((s->a << 35) | (s->a >> 29)) ^ s->b; s->b += 111111111111111111ULL; s->c = (block << 23) | (block >> 41); return block; }

License

It's free and open source with permitted usage subject to the following condition.

The function name eightomic_prng_c_64() must not change.

Reference

eightomic_prng_c_64() is the randomization function that accepts the following argument.

1: s is the struct eightomic_prng_c_64_s pointer with 3 uint64_t integers s->a, s->b and s->c. Each must be initialized with any combination of values.

The return value data type is uint64_t.

It returns a 64-bit unsigned integer pseudorandom number result.

Period

It has an approximated maximum period of between 2⁶⁶ and 2¹²⁸.

It has a minimum period of 2⁶⁶.

An odd-numbered constant sums with s->b for 2⁶⁴ different numbers to XOR with s->a in each cycle. Then, the minimum period increases from 2⁶⁴ to 2⁶⁶ based on the small cycle verification from PRNG C 8.

Incrementing s->b outside of eightomic_prng_c_64() behaves as an interdimensional jump function that starts a different number cycle, resulting in at least 2⁶⁴ different number cycles.

Speed

It's possibly the fastest 64-bit PRNG that both generates numbers individually and passes extensive statistical tests within a medium period.

Security

There aren't any broken number cycles smaller than the aforementioned proven minimum period of 2⁶⁶.

Zeroland escapes quickly after generating 3 subsequent numbers.

Randomness

The following code outputs a cycle of 512 pseudorandom numbers from all bits seeded with 0.

#include <stdint.h> #include <stdio.h> struct eightomic_prng_c_64_s { uint64_t a; uint64_t b; uint64_t c; }; uint64_t eightomic_prng_c_64(struct eightomic_prng_c_64_s *s) { uint64_t block = s->a + s->c; s->a = ((s->a << 35) | (s->a >> 29)) ^ s->b; s->b += 111111111111111111ULL; s->c = (block << 23) | (block >> 41); return block; } int main(void) { struct eightomic_prng_c_64_s s = { .a = 0, .b = 0, .c = 0 }; uint16_t i = 0; printf("%20llu", eightomic_prng_c_64(&s)); while (i < 512) { printf(" %20llu", eightomic_prng_c_64(&s)); i++; if ((i % 3) == 0) { printf("\n%20llu", eightomic_prng_c_64(&s)); } } return 0; }

The following truncated output from the aforementioned code demonstrates strong randomness with visually-acceptable distribution at first glance after escaping zeroland.

0 0 111111111111111111 11230046796561897873 2881363010509912191 11297234668251327220 1388670456593482054 4005456890639021794 12170537226354249753 3993868278322938451 17622409659581805434 712543724815272738 536057390720967786 13919493511741695284 8539160466794972700 14718221320505250691 13791374196662554522 8029039440196916512 3300013340820700608 9472808757467613219 7113512351285152229 8571044366814176728 17565429618975520072 4945125870479137608 16064532453754716626 3732586290931914683 8732650904036191065 3259070989511032462 397127175185663886 17801460070891356848 17417121579173474077 17850406831885185035 14546930543202694542 11473773644502038326 5576455552076482507 10348623139509963255 16243158820994926553 8871781916232770227 3655188588621363007 13709328999297108772 798384959661900852 8215726484323073826 8963886448163778900 14019438937113194631 5677470171566158174 2268448786916553178 10922810741765364507 3699878254625660869 15592372952842809011 965365368586781956 14618297881106440358 13304824949203794364 1288133026224803428 14871152630962244920 17046107934919360071 8454964316085632095 1408806118605713100 13313847757147441579 1473187076924241816 4755750281639583849 14854009331078546735 4495027144470717554 9059563249064447571 14355550692166463380

The distribution properties of the aforementioned interdimensional period are similar to a counter-based RNG that eventually generates 1 of each number in a 2⁶⁴ range when using interdimensional jumps.

Without interdimensional jumps, each individual 2⁶⁶ period emulates non-deterministic probability where some numbers may be repeated and some numbers may be missing.