Formatted random_r.c

This commit is contained in:
wiire-a 2017-11-08 21:12:19 +01:00
parent 22f96521fc
commit cb615a1a08

View File

@ -22,6 +22,10 @@
* Rewritten to be reentrant by Ulrich Drepper, 1995 * Rewritten to be reentrant by Ulrich Drepper, 1995
*/ */
/*
* This file is part of pixiewps and was modified
*/
#include <limits.h> #include <limits.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
@ -82,65 +86,59 @@ struct m_random_data {
dominant factor. With deg equal to seven, the period is actually much dominant factor. With deg equal to seven, the period is actually much
longer than the 7*(2**7 - 1) predicted by this formula. */ longer than the 7*(2**7 - 1) predicted by this formula. */
/* For each of the currently supported random number generators, we have a /* For each of the currently supported random number generators, we have a
break value on the amount of state information (you need at least this many break value on the amount of state information (you need at least this many
bytes of state info to support this random number generator), a degree for bytes of state info to support this random number generator), a degree for
the polynomial (actually a trinomial) that the R.N.G. is based on, and the polynomial (actually a trinomial) that the R.N.G. is based on, and
separation between the two lower order coefficients of the trinomial. */ separation between the two lower order coefficients of the trinomial. */
/* Linear congruential. */ /* Linear congruential */
#define TYPE_0 0 #define TYPE_0 0
#define BREAK_0 8 #define BREAK_0 8
#define DEG_0 0 #define DEG_0 0
#define SEP_0 0 #define SEP_0 0
/* x**7 + x**3 + 1. */ /* x**7 + x**3 + 1 */
#define TYPE_1 1 #define TYPE_1 1
#define BREAK_1 32 #define BREAK_1 32
#define DEG_1 7 #define DEG_1 7
#define SEP_1 3 #define SEP_1 3
/* x**15 + x + 1. */ /* x**15 + x + 1 */
#define TYPE_2 2 #define TYPE_2 2
#define BREAK_2 64 #define BREAK_2 64
#define DEG_2 15 #define DEG_2 15
#define SEP_2 1 #define SEP_2 1
/* x**31 + x**3 + 1. */ /* x**31 + x**3 + 1 */
#define TYPE_3 3 #define TYPE_3 3
#define BREAK_3 128 #define BREAK_3 128
#define DEG_3 31 #define DEG_3 31
#define SEP_3 3 #define SEP_3 3
/* x**63 + x + 1. */ /* x**63 + x + 1 */
#define TYPE_4 4 #define TYPE_4 4
#define BREAK_4 256 #define BREAK_4 256
#define DEG_4 63 #define DEG_4 63
#define SEP_4 1 #define SEP_4 1
/* Array versions of the above information to make code run faster. /* Array versions of the above information to make code run faster.
Relies on fact that TYPE_i == i. */ Relies on fact that TYPE_i == i */
#define MAX_TYPES 5 /* Max number of types above. */ #define MAX_TYPES 5 /* Max number of types above */
struct m_random_poly_info struct m_random_poly_info {
{
/* smallint seps[MAX_TYPES]; */ /* smallint seps[MAX_TYPES]; */
/* smallint degrees[MAX_TYPES]; */ /* smallint degrees[MAX_TYPES]; */
unsigned char seps[MAX_TYPES]; unsigned char seps[MAX_TYPES];
unsigned char degrees[MAX_TYPES]; unsigned char degrees[MAX_TYPES];
}; };
static const struct m_random_poly_info random_poly_info = static const struct m_random_poly_info random_poly_info = {
{
{SEP_0, SEP_1, SEP_2, SEP_3, SEP_4}, {SEP_0, SEP_1, SEP_2, SEP_3, SEP_4},
{DEG_0, DEG_1, DEG_2, DEG_3, DEG_4} {DEG_0, DEG_1, DEG_2, DEG_3, DEG_4}
}; };
/* If we are using the trivial TYPE_0 R.N.G., just do the old linear /* If we are using the trivial TYPE_0 R.N.G., just do the old linear
congruential bit. Otherwise, we do our fancy trinomial stuff, which is the congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
same in all the other cases due to all the global variables that have been same in all the other cases due to all the global variables that have been
@ -161,31 +159,26 @@ void m_random_r(struct m_random_data *buf, int32_t *result)
state = buf->state; state = buf->state;
if (buf->rand_type == TYPE_0) if (buf->rand_type == TYPE_0) {
{
int32_t val = state[0]; int32_t val = state[0];
val = ((state[0] * 1103515245) + 12345) & 0x7fffffff; val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
state[0] = val; state[0] = val;
*result = val; *result = val;
} } else {
else
{
int32_t *fptr = buf->fptr; int32_t *fptr = buf->fptr;
int32_t *rptr = buf->rptr; int32_t *rptr = buf->rptr;
int32_t *end_ptr = buf->end_ptr; int32_t *end_ptr = buf->end_ptr;
int32_t val; int32_t val;
val = *fptr += *rptr; val = *fptr += *rptr;
/* Chucking least random bit. */ /* Chucking least random bit. */
*result = (val >> 1) & 0x7fffffff; *result = (val >> 1) & 0x7fffffff;
++fptr; ++fptr;
if (fptr >= end_ptr) if (fptr >= end_ptr) {
{
fptr = state; fptr = state;
++rptr; ++rptr;
} } else {
else
{
++rptr; ++rptr;
if (rptr >= end_ptr) if (rptr >= end_ptr)
rptr = state; rptr = state;
@ -201,7 +194,6 @@ void m_random_r(struct m_random_data *buf, int32_t *result)
} }
/* libc_hidden_def(random_r) */ /* libc_hidden_def(random_r) */
/* Initialize the random number generator based on the given seed. If the /* Initialize the random number generator based on the given seed. If the
type is the trivial no-state-information type, just remember the seed. type is the trivial no-state-information type, just remember the seed.
Otherwise, initializes state[] based on the given "seed" via a linear Otherwise, initializes state[] based on the given "seed" via a linear
@ -221,14 +213,17 @@ int m_srandom_r (unsigned int seed, struct m_random_data *buf)
if (buf == NULL) if (buf == NULL)
goto fail; goto fail;
type = buf->rand_type; type = buf->rand_type;
if ((unsigned int)type >= MAX_TYPES) if ((unsigned int)type >= MAX_TYPES)
goto fail; goto fail;
state = buf->state; state = buf->state;
/* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */ /* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */
if (seed == 0) if (seed == 0)
seed = 1; seed = 1;
state[0] = seed; state[0] = seed;
if (type == TYPE_0) if (type == TYPE_0)
goto done; goto done;
@ -236,8 +231,7 @@ int m_srandom_r (unsigned int seed, struct m_random_data *buf)
dst = state; dst = state;
word = seed; word = seed;
kc = buf->rand_deg; kc = buf->rand_deg;
for (i = 1; i < kc; ++i) for (i = 1; i < kc; ++i) {
{
/* This does: /* This does:
state[i] = (16807 * state[i - 1]) % 2147483647; state[i] = (16807 * state[i - 1]) % 2147483647;
but avoids overflowing 31 bits. */ but avoids overflowing 31 bits. */
@ -252,8 +246,7 @@ int m_srandom_r (unsigned int seed, struct m_random_data *buf)
buf->fptr = &state[buf->rand_sep]; buf->fptr = &state[buf->rand_sep];
buf->rptr = &state[0]; buf->rptr = &state[0];
kc *= 10; kc *= 10;
while (--kc >= 0) while (--kc >= 0) {
{
int32_t discard; int32_t discard;
(void)m_random_r(buf, &discard); (void)m_random_r(buf, &discard);
} }
@ -266,7 +259,6 @@ fail:
} }
/* libc_hidden_def(srandom_r) */ /* libc_hidden_def(srandom_r) */
/* Initialize the state information in the given array of N bytes for /* Initialize the state information in the given array of N bytes for
future random number generation. Based on the number of bytes we future random number generation. Based on the number of bytes we
are given, and the break values for the different R.N.G.'s, we choose are given, and the break values for the different R.N.G.'s, we choose
@ -290,10 +282,8 @@ int m_initstate_r (unsigned int seed, char *arg_state, size_t n, struct m_random
if (n >= BREAK_3) if (n >= BREAK_3)
type = n < BREAK_4 ? TYPE_3 : TYPE_4; type = n < BREAK_4 ? TYPE_3 : TYPE_4;
else if (n < BREAK_1) else if (n < BREAK_1) {
{ if (n < BREAK_0) {
if (n < BREAK_0)
{
/* __set_errno (EINVAL); */ /* __set_errno (EINVAL); */
goto fail; goto fail;
} }
@ -306,12 +296,13 @@ int m_initstate_r (unsigned int seed, char *arg_state, size_t n, struct m_random
separation = random_poly_info.seps[type]; separation = random_poly_info.seps[type];
buf->rand_type = type; buf->rand_type = type;
buf->rand_sep = separation; buf->rand_sep = separation;
buf->rand_deg = degree; buf->rand_deg = degree;
state = &((int32_t *)arg_state)[1]; /* First location. */ state = &((int32_t *)arg_state)[1]; /* First location. */
/* Must set END_PTR before srandom. */ /* Must set END_PTR before srandom. */
buf->end_ptr = &state[degree]; buf->end_ptr = &state[degree];
buf->state = state; buf->state = state;
m_srandom_r(seed, buf); m_srandom_r(seed, buf);
@ -328,7 +319,6 @@ fail:
} }
/* libc_hidden_def(initstate_r) */ /* libc_hidden_def(initstate_r) */
/* Restore the state from the given state array. /* Restore the state from the given state array.
Note: It is important that we also remember the locations of the pointers Note: It is important that we also remember the locations of the pointers
in the current state information, and restore the locations of the pointers in the current state information, and restore the locations of the pointers
@ -364,13 +354,13 @@ int m_setstate_r (char *arg_state, struct m_random_data *buf)
buf->rand_sep = separation = random_poly_info.seps[type]; buf->rand_sep = separation = random_poly_info.seps[type];
buf->rand_type = type; buf->rand_type = type;
if (type != TYPE_0) if (type != TYPE_0) {
{
int rear = new_state[-1] / MAX_TYPES; int rear = new_state[-1] / MAX_TYPES;
buf->rptr = &new_state[rear]; buf->rptr = &new_state[rear];
buf->fptr = &new_state[(rear + separation) % degree]; buf->fptr = &new_state[(rear + separation) % degree];
} }
buf->state = new_state; buf->state = new_state;
/* Set end_ptr too. */ /* Set end_ptr too. */
buf->end_ptr = &new_state[degree]; buf->end_ptr = &new_state[degree];