user6646922
user6646922

Reputation: 517

glibc rand() doesn't work with python but works fine in online compiler

I'm trying to embed a glibc rand() function into python. My purpose is to predict the next values of rand() basing on the assumption that is uses an LCG. I've read that it only uses LCG if it's operating on an 8-byte state, so I'm trying to use the initstate method to set that.

I have the following code in my glibc_random.c file:

#include <stdlib.h>
#include "glibc_random.h"

void initialize()
{
    unsigned int seed = 1;
    char state[8];

    initstate(seed, state, sizeof(state));
}

long int call_glibc_random()
{
    long r = rand();
    return r;
}

And the following in the respective glibc_random.h:

void initialize();
long int call_glibc_random();

Code in python:

def test():
    glibc_random.initialize()
    number_of_initial_values = 10
    number_of_values_to_predict = 5
    initial_values = []

    for i in range(number_of_initial_values):
        initial_values.extend([glibc_random.call_glibc_random()])

When invoked in python, the code above keeps adding 12345 to my list of initial_values. However, when running the C code in www.onlinegdb.com I get a more reasonable list of numbers (11035275900, 3774015750, etc.). I can only reproduce my problem in onlinegdb when I use setstate(state) after the call to initstate(seed, state, sizeof(state)) in the initialize() method.

Can anybody suggest what is wrong here? I'm using swig and python2.7, btw.

Upvotes: 1

Views: 216

Answers (1)

Pablo
Pablo

Reputation: 13580

I have never used initstate before but

void initialize()
{
    unsigned int seed = 1;
    char state[8];

    initstate(seed, state, sizeof(state));
}

seems wrong to me. state is a local variable of initialize and when the function ends, the variable ceases to exit, so rand() might give you garbage because it is trying to access a pointer that is no longer valid anymore.

You can declare state as static so that it doesn't cease to exist when initialize end,

void initialize()
{
    unsigned int seed = 1;
    static char state[8];

    initstate(seed, state, sizeof(state));
}

or make state a global variable.

char state[8];

void initialize()
{
    unsigned int seed = 1;

    initstate(seed, state, sizeof(state));
}

Upvotes: 4

Related Questions