/*
Fixed points for Bob Jenkins's small non-crypto PRNG.

They're impossible to reach with the official seeding method, though.

I found these with my solver.

- yarrkov, 21.04.2009
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint32_t u4;
typedef struct ranctx { u4 a; u4 b; u4 c; u4 d; } ranctx;

#define rot(x,k) (((x)<<(k))|((x)>>(32-(k))))
u4 ranval( ranctx *x ) {
    u4 e = x->a - rot(x->b, 27);
    x->a = x->b ^ rot(x->c, 17);
    x->b = x->c + x->d;
    x->c = x->d + e;
    x->d = e + x->a;
    return x->d;
}

/*
fixed points:

00000000 00000000 00000000 00000000
77777777 55555555 11111111 44444444
5591F2E3 69EBA6CD 2A171E3D 3FD48890
47CB8D56 AE9B35A7 5C78F4A8 522240FF
*/

#define NUM 10

int main()
{
    ranctx ctx;

    ctx.a = 0x47CB8D56;
    ctx.b = 0xAE9B35A7;
    ctx.c = 0x5C78F4A8;
    ctx.d = 0x522240FF;

    printf("Generating %u values with Jenkins small PRNG...\n", NUM);
    printf("Initial state: %08X %08X %08X %08X\n", ctx.a, ctx.b, ctx.c, ctx.d);

    int i;
    for(i=0;i<NUM;i++)
        printf("%08X\n", ranval(&ctx));

    return 0;
}
