123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- #include <features.h>
- #include <errno.h>
- #include <limits.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <unistd.h>
- #define TYPE_0 0
- #define BREAK_0 8
- #define DEG_0 0
- #define SEP_0 0
- #define TYPE_1 1
- #define BREAK_1 32
- #define DEG_1 7
- #define SEP_1 3
- #define TYPE_2 2
- #define BREAK_2 64
- #define DEG_2 15
- #define SEP_2 1
- #define TYPE_3 3
- #define BREAK_3 128
- #define DEG_3 31
- #define SEP_3 3
- #define TYPE_4 4
- #define BREAK_4 256
- #define DEG_4 63
- #define SEP_4 1
- #define MAX_TYPES 5
- struct random_poly_info
- {
- smallint seps[MAX_TYPES];
- smallint degrees[MAX_TYPES];
- };
- static const struct random_poly_info random_poly_info =
- {
- { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 },
- { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }
- };
- int random_r(struct random_data *buf, int32_t *result)
- {
- int32_t *state;
- if (buf == NULL || result == NULL)
- goto fail;
- state = buf->state;
- if (buf->rand_type == TYPE_0)
- {
- int32_t val = state[0];
- val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
- state[0] = val;
- *result = val;
- }
- else
- {
- int32_t *fptr = buf->fptr;
- int32_t *rptr = buf->rptr;
- int32_t *end_ptr = buf->end_ptr;
- int32_t val;
- val = *fptr += *rptr;
-
- *result = (val >> 1) & 0x7fffffff;
- ++fptr;
- if (fptr >= end_ptr)
- {
- fptr = state;
- ++rptr;
- }
- else
- {
- ++rptr;
- if (rptr >= end_ptr)
- rptr = state;
- }
- buf->fptr = fptr;
- buf->rptr = rptr;
- }
- return 0;
- fail:
- __set_errno (EINVAL);
- return -1;
- }
- libc_hidden_def(random_r)
- int srandom_r (unsigned int seed, struct random_data *buf)
- {
- int type;
- int32_t *state;
- long int i;
- long int word;
- int32_t *dst;
- int kc;
- if (buf == NULL)
- goto fail;
- type = buf->rand_type;
- if ((unsigned int) type >= MAX_TYPES)
- goto fail;
- state = buf->state;
-
- if (seed == 0)
- seed = 1;
- state[0] = seed;
- if (type == TYPE_0)
- goto done;
- dst = state;
- word = seed;
- kc = buf->rand_deg;
- for (i = 1; i < kc; ++i)
- {
-
- long int hi = word / 127773;
- long int lo = word % 127773;
- word = 16807 * lo - 2836 * hi;
- if (word < 0)
- word += 2147483647;
- *++dst = word;
- }
- buf->fptr = &state[buf->rand_sep];
- buf->rptr = &state[0];
- kc *= 10;
- while (--kc >= 0)
- {
- int32_t discard;
- (void) random_r (buf, &discard);
- }
- done:
- return 0;
- fail:
- return -1;
- }
- libc_hidden_def(srandom_r)
- int initstate_r (unsigned int seed, char *arg_state, size_t n, struct random_data *buf)
- {
- int type;
- int degree;
- int separation;
- int32_t *state;
- if (buf == NULL)
- goto fail;
- if (n >= BREAK_3)
- type = n < BREAK_4 ? TYPE_3 : TYPE_4;
- else if (n < BREAK_1)
- {
- if (n < BREAK_0)
- {
- __set_errno (EINVAL);
- goto fail;
- }
- type = TYPE_0;
- }
- else
- type = n < BREAK_2 ? TYPE_1 : TYPE_2;
- degree = random_poly_info.degrees[type];
- separation = random_poly_info.seps[type];
- buf->rand_type = type;
- buf->rand_sep = separation;
- buf->rand_deg = degree;
- state = &((int32_t *) arg_state)[1];
-
- buf->end_ptr = &state[degree];
- buf->state = state;
- srandom_r (seed, buf);
- state[-1] = TYPE_0;
- if (type != TYPE_0)
- state[-1] = (buf->rptr - state) * MAX_TYPES + type;
- return 0;
- fail:
- __set_errno (EINVAL);
- return -1;
- }
- libc_hidden_def(initstate_r)
- int setstate_r (char *arg_state, struct random_data *buf)
- {
- int32_t *new_state = 1 + (int32_t *) arg_state;
- int type;
- int old_type;
- int32_t *old_state;
- int degree;
- int separation;
- if (arg_state == NULL || buf == NULL)
- goto fail;
- old_type = buf->rand_type;
- old_state = buf->state;
- if (old_type == TYPE_0)
- old_state[-1] = TYPE_0;
- else
- old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type;
- type = new_state[-1] % MAX_TYPES;
- if (type < TYPE_0 || type > TYPE_4)
- goto fail;
- buf->rand_deg = degree = random_poly_info.degrees[type];
- buf->rand_sep = separation = random_poly_info.seps[type];
- buf->rand_type = type;
- if (type != TYPE_0)
- {
- int rear = new_state[-1] / MAX_TYPES;
- buf->rptr = &new_state[rear];
- buf->fptr = &new_state[(rear + separation) % degree];
- }
- buf->state = new_state;
-
- buf->end_ptr = &new_state[degree];
- return 0;
- fail:
- __set_errno (EINVAL);
- return -1;
- }
- libc_hidden_def(setstate_r)
|