Skip to content

Instantly share code, notes, and snippets.

@erthink
Last active October 4, 2017 13:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save erthink/6666dcb8f76118acbfe7336e69a69806 to your computer and use it in GitHub Desktop.
Save erthink/6666dcb8f76118acbfe7336e69a69806 to your computer and use it in GitHub Desktop.
ly-random
#include <stdint.h>
static unsigned rnd_head, rnd_tail;
static uint32_t rnd_pool[64];
static __inline
uint32_t random_poly (unsigned n)
{
/* LY: доступ к ряду полинома через циклический буфер. */
return rnd_pool [(rnd_tail + n) & 63];
}
static __inline
uint32_t random_rol (uint32_t v, unsigned s)
{
/* LY: циклический сдвиг влево. */
return (v << s) | (v >> (32 - s));
}
void random_salt (unsigned salt)
{
/* LY: подсаливаем генератор случайностью. */
rnd_pool[rnd_head++ & 63] += salt;
}
uint32_t random_get (void)
{
/* LY: Генератор случайных числел на основе неприводимого
полинома X^64 + X^4 + X^3 + X и нелинейной функции обратной связи
отдаленно подобно вихрю Мерсенна (Mersenne twister).
(C) 2003 Leo Yuriev
*/
uint32_t v =
random_poly (0)
^ random_poly (1)
^ random_poly (62)
^ random_poly (61);
uint32_t s = 0xb7e15163ul
+ random_rol (random_poly (11), 5)
+ random_rol (random_poly (23), 7)
+ random_rol (random_poly (37), 1);
v += s;
rnd_pool[++rnd_tail & 63] = v;
return v;
}
void random_init ( unsigned seed) {
/* LY: инициализируем и разогреваем генератор. */
int i;
rnd_head = rnd_tail = 0;
for(i = 0; i < 64; ++i)
rnd_pool[i] = 0;
random_salt (seed);
for(i = 0; i < 64 * 64; ++i)
random_get ();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment