简体   繁体   中英

Conflict between uuid.uuid() from Python and std::rand() from C++

My soft is written in C++ and called by python scripts (through Swig). When the python function uuid.uuid1() is called in the scripts, the seed used by std::rand() of C++ seems lost. It's a problem beacause I have to be able to relaunch my soft with exactly the same behaviour in the C++ code (it's not a matter for uniqid's).

The problem is simplified in the following example :

C++ file testrand.h :

#ifndef __INCLUDE__TESTRAND_H__
#define __INCLUDE__TESTRAND_H__

void initialize(unsigned long int seed);
unsigned long int get_number();

#endif

C++ file testrand.cpp :

#include "testrand.h" 
#include <cstdlib>

void initialize(unsigned long int seed)
{
    std::srand(seed);
}

unsigned long int get_number()
{
    return std::rand();
}

Swig file testrand.i :

%module testrand
%{
    #include "testrand.h" 
%}
%include "testrand.h"

The compilation is done with the following command :

swig -python -c++ testrand.i
g++ -c -fPIC testrand.cpp testrand_wrap.cxx -I/usr/include/python2.7/
g++ -shared testrand.o testrand_wrap.o -o _testrand.so

If I launch the following python testcase several times, I can see that the first number is always the same (as expected), but the second number, generated after the call of uuid.uuid1() changes at each run.

import testrand
import uuid

testrand.initialize(10)

x1 = testrand.get_number()
print x1

uuid.uuid1()

x2 = testrand.get_number()
print x2

Several runs :

> python testcase.py 
1215069295
1691632206

> python testcase.py 
1215069295
746144017

> python testcase.py 
1215069295
377602282

Have you any idea how I can use python uuid without killing my C++ seed ? Thanks in advance. (EDIT : my configuration : Linux openSUSE 12.3, 64 bits, python 2.7.3 (but same problem with 2.7.2), swig 2.0.9, gcc 4.7.2 (but same problem with 4.5.1))

I found the code of uuid here : http://pythoninside.com/en/source-code/2.7.5/uuid/uuid.py and I copied and used the code in the example script (ie without import uuid). The problem comes from the call _uuid_generate_time(_buffer) at line 500. This function is defined as an alias of ctypes.CDLL(ctypes.util.find_library('uuid')).uuid_generate_time at lines 402-410. This is the only mention of the bug I found : https://savannah.cern.ch/bugs/?24456

Possibly you need to use uuid.uuid4() in your python code.

uuid1() is generated from a host ID, sequence number, and the current time, where as uuid4() is generated randomly.

(Although a question still remains: if uuid1() really does use the current time, then how can it ever produce the same uuid, as is seen here in each of the first runs.)

I found a solution to get around the problem. Actually, the C++ seed is initialized by the uuid module only once (at the first call of the function uuid.uuid1() ). If I change my example script by adding a useless first call to the function I don't have the problem :

import testrand
import uuid

uuid.uuid1()
testrand.initialize(10)

x1 = testrand.get_number()
print x1

uuid.uuid1()

x2 = testrand.get_number()
print x2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM