/* 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. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #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); } }