/* Written in 2018 by Sebastiano Vigna (vigna@acm.org) Emits the output of a PCG generator passed through a simple bijection. To the extent possible under law, the author has dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. See . */ #include #include #include #include #include // ------- // PCG code Copyright by Melissa O'Neill #define PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL #define PCG_DEFAULT_INCREMENT_64 1442695040888963407ULL struct pcg_state_64 { uint64_t state; } rng; inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng) { rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + PCG_DEFAULT_INCREMENT_64; } inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state) { uint64_t word = ((state >> ((state >> 59u) + 5u)) ^ state) * 12605985483714917081ull; return (word >> 43u) ^ word; } inline uint64_t pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng) { uint64_t oldstate = rng->state; pcg_oneseq_64_step_r(rng); return pcg_output_rxs_m_xs_64_64(oldstate); } // ------- // Emits the output of a PCG generator passed throgh a very simple bijection. // Give an initial 64-bit state and pipe the output in PractRand. int main(int argc, char* argv[]) { if (argc != 2) { fprintf(stderr, "USAGE: %s STATE\n", argv[0]); exit(1); } const uint64_t initial = strtoull(argv[1], NULL, 0); if (errno) { fprintf(stderr, "%s\n", strerror(errno)); exit(1); } rng.state = initial; for(;;) { uint64_t out = pcg_oneseq_64_rxs_m_xs_64_random_r(&rng); out ^= out >> 43; // bijection fwrite(&out, sizeof out, 1, stdout); } }