-2

I want to convert the following C code to python :

timeVar = time((time_t *)0x0)
seed = (uint)timeVar;
srand(seed);
random_value1 = rand();
random_value2 = rand();
random_value3 = rand();

Basically, i have a seed used in the C code i provided earlier, and i want to make the same code in python to predict the next values based on the seed i have.

Edit : I found that it can be solved with ctypes module.

bd55
  • 55
  • 7
  • 4
    You will have to find the source code of `rand` function in your specific standard C library, and see how it is implemented. There is no mandated standard algorithm. – Eugene Sh. Feb 22 '23 at 16:39
  • 1
    Do you mean you want to create a Python program that generates the same numbers that the C program's calls to `rand()` do? – John Bollinger Feb 22 '23 at 16:40
  • @JohnBollinger exactly. – bd55 Feb 22 '23 at 16:40
  • Say, you have mimicked the algorithm. How do you plan seeding it with the same value? – Eugene Sh. Feb 22 '23 at 16:42
  • 1
    Well then, you'll need to designate a scope for that sameness. C does not specify what psuedo-random number generator will support `rand()`, or what the range of its results should be, and these differ among real-world C implementations. Perhaps you want the same as some particular C implementation available on the same host? – John Bollinger Feb 22 '23 at 16:42
  • @EugeneSh. Yes, i want to basically convert the C code to python. The seed i will use is the same. I just want to get the same random numbers as in C. – bd55 Feb 22 '23 at 16:44
  • @JohnBollinger the problem is i cant view the implementation of rand. I am given a C pseudocode which i have analyzed in the ghidra tool and i have to mimic its functionality in python code and get the same results as this C program creates. – bd55 Feb 22 '23 at 16:46
  • 2
    @bd55 Wouldn't it be sufficient to know that it is generating *some* pseudo-random number between `0` and `RAND_MAX` (whose value is implementation defined too..) ? – Eugene Sh. Feb 22 '23 at 16:51
  • I think the easiest (and maybe only viable) way would be to use `ctypes` to call the C functions directly from Python. – Michael Butscher Feb 22 '23 at 16:51
  • 1
    C is a specification, and it intentionally does not specify how pseudo-random numbers are generated. Different C implementations will produce different pseudo-random sequences even when seeded with the same value. So there is no such thing as "same random numbers as in C". – n. m. could be an AI Feb 22 '23 at 16:54
  • I read that when not an upperbound is supplied, the number 32767 is used as default. Is this a possibility? – bd55 Feb 22 '23 at 16:57
  • @bd55 No. It is implementation defined. https://ideone.com/CqyJyj . `RAND_MAX` has to be equal or greater than `32767` though – Eugene Sh. Feb 22 '23 at 16:58
  • FWIW, the C standard does provide an **example** of `srand/rand` implementation: http://port70.net/~nsz/c/c11/n1570.html#7.22.2.2p5 – Eugene Sh. Feb 22 '23 at 17:01
  • 1
    For your edit - you *must* know the specific `rand` implementation.. Unless your encryption algorithm is vulnerable and can be reversed or brute-forced without it, which could be the exact point of this exercise... – Eugene Sh. Feb 22 '23 at 17:06
  • @bd55 "There is no upper bound given in rand()." is inaccurate. The upper bound, inclusive, is `RAND_MAX`, an `int`. It is at least 0x7FFF. `RAND_MAX <= INT_MAX`. – chux - Reinstate Monica Feb 22 '23 at 17:44
  • "I have been given the seed so that i can predict the random values used in the encryption operations." lacks knowing the number of times `rand()` was called prior to its use in "the encryption operations". Although there are at most `UINT_MAX+1` initial states for `rand()`, the number of states may be far far larger. – chux - Reinstate Monica Feb 22 '23 at 17:58

3 Answers3

2

i want to basically convert the C code to python. The seed i will use is the same. I just want to get the same random numbers as in C

You cannot reliably do this in a broad sense, because the C program will not generate the same random numbers as itself on all machines. "The same random numbers as in C" is not well defined.

Getting the same random numbers as does the C program on the same host is a more approachable problem, but to the best of my knowledge, Python does not provide any built-in interface to the C implementation's rand(). In particular, random.random() implements a specific algorithm which differs from the one provided by at least some C libraries' rand(), and os.urandom() provides a randomness source that is more cryptographically secure than C's rand() typically is (and therefore is different).

The easiest way to generate the same numbers that your C library's rand() does would be to use C's rand(). That is, write a native extension by which you can call the C library's rand(), or use one of the other available mechanisms for accessing native functions.

If that's not allowed, then to generate the same results that the system's rand() does, you'll need to reverse-engineer the system's rand(). If you need to do that without reviewing its source, then perhaps you can find sufficient information in its documentation. If you need to do the reverse-engineering from scratch, then you probably have a difficult road ahead.

If you need to match the C library's rand() without using it directly and without reverse-engineering the specific one you're trying to mimic, then you're pretty much toast. If this is an academic exercise and that's what you think it's asking, then you've probably misunderstood the requirements.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • 1
    One could write a small C program with the given seed to dump first zillion (or just as many as needed) of `rand` results, and use as lookup table. In case we are talking about same host/toolchain. – Eugene Sh. Feb 22 '23 at 17:11
  • Good point, @EugeneSh.. Generating a bounded number of the same numbers that the hosts's `rand()` does *when starting from a specific seed* is an easier problem than reproducing `rand()`'s behavior generally, which is where this answer focuses. Though your suggestion does still boil down to using C's `rand()`. – John Bollinger Feb 22 '23 at 17:14
2

Using the ctypes module would let you call rand from libc. Whether this is the same rand as is being used by your program is a different matter (e.g. it might be statically linked to another implemention of rand) but it might work!

from ctypes import CDLL
from ctypes.util import find_library

libc = CDLL(find_library("c"))

libc.srand(0x5a35b162)
print(libc.rand(), libc.rand(), libc.rand())

Note that Python doesn't know the prototypes of these methods, but given the're small integer values it likely doesn't matter much. But have a read of the section on foreign functions if you're interested.

Sam Mason
  • 15,216
  • 1
  • 41
  • 60
1

The rand() function in C generates a random number between 0 and RAND_MAX, which is typically a large number defined in the stdlib.h library. In Python, we can use the random module to generate random numbers. The random module provides several functions to generate random numbers, including randint(), uniform(), and random(). However, to mimic the rand() function of C, we can use the randint() function.

The randint() function in Python generates a random integer between two specified numbers. To mimic the rand() function of C, we can specify the range between 0 and RAND_MAX. We can obtain the value of RAND_MAX in Python by importing the sys module and accessing the maxsize attribute of the maxsize class. The maxsize attribute returns the largest positive integer that can be used as an index for a sequence.

Here is an example code that mimics the rand() function of C in Python using the randint() function:

import random
import sys

# define RAND_MAX
RAND_MAX = sys.maxsize

# generate random number between 0 and RAND_MAX
random_number = random.randint(0, RAND_MAX)

# print random number
print("Random number: ", random_number)

In this code, we first import the random module and the sys module. We define RAND_MAX as the maxsize attribute of the sys.maxsize class, which returns the largest positive integer that can be used as an index for a sequence. We then use the randint() function to generate a random integer between 0 and RAND_MAX, and store the result in the random_number variable. Finally, we print the value of the random_number variable.

The randint() function generates a random integer between the two specified numbers, inclusive. Therefore, the code above generates a random integer between 0 and the largest positive integer that can be used as an index for a sequence in Python, which is equivalent to the range of the rand() function in C.

In summary, to mimic the rand() function of C in Python, we can use the randint() function in the random module, specifying the range between 0 and the largest positive integer that can be used as an index for a sequence in Python, which can be obtained from the sys module.