#include #include #include #include #include struct rc4rand_state { uint_fast8_t x, y; uint8_t data[256]; }; /* initialize with a seed of any size */ static void rc4rand_seed(struct rc4rand_state *st, size_t len, const void *data) { unsigned i, j; uint_fast8_t tmp; for (i = 0; i < 256; i++) st->data[i] = i; for (i = j = 0; i < 256; i++) { j = (j + ((unsigned char *)data)[i % len] + st->data[i]) & 255; tmp = st->data[i]; st->data[i] = st->data[j]; st->data[j] = tmp; } st->x = st->y = 0; } /* generate an arbitrarily long sequence or pseudo-random bits */ static void rc4rand(struct rc4rand_state *st, size_t len, void *out) { size_t i; uint_fast8_t tmp; for (i = 0; i < len; i++) { unsigned m; st->x = (st->x + 1) & 255; st->y = (st->y + st->data[st->x]) & 255; tmp = st->data[st->x]; st->data[st->x] = st->data[st->y]; st->data[st->y] = tmp; ((unsigned char*)out)[i] = st->data[(st->data[st->x] + st->data[st->y]) & 255]; } } /* capture 32-bits in the native byte order */ static uint32_t rc4rand32(struct rc4rand_state *st) { union { uint32_t u; unsigned char c[sizeof(uint32_t)]; } buf; rc4rand(st, sizeof buf, &buf); return buf.u; } /* capture 64-bits in the native byte order */ static uint64_t rc4rand64(struct rc4rand_state *st) { union { uint64_t u; unsigned char c[sizeof(uint64_t)]; } buf; rc4rand(st, sizeof buf, &buf); return buf.u; } /* capture 32-bits in little endian byte order */ static uint32_t rc4rand32le(struct rc4rand_state *st) { unsigned char buf[4] = { 0, 0, 0, 0 }; rc4rand(st, sizeof buf, &buf); return buf[0] | ((uint32_t)buf[1] << 8) | ((uint32_t)buf[2] << 16) | ((uint32_t)buf[3] << 24); } /* capture 64-bits in little endian byte order */ static uint64_t rc4rand64le(struct rc4rand_state *st) { unsigned char buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; rc4rand(st, sizeof buf, &buf); return buf[0] | ((uint64_t)buf[1] << 8) | ((uint64_t)buf[2] << 16) | ((uint64_t)buf[3] << 24) | ((uint64_t)buf[4] << 32) | ((uint64_t)buf[5] << 40) | ((uint64_t)buf[6] << 48) | ((uint64_t)buf[7] << 56); } /*** example code ***/ int main() { struct rc4rand_state seed; int i; uint64_t m; struct timeval tv; gettimeofday(&tv, 0); rc4rand_seed(&seed, sizeof tv, &tv); for(i = 0; i < 20; i++) { m = rc4rand64le(&seed); printf("0x%016llx\n", m); } return 0; }