Skip to main content

Predict python's random module random generated values

Project description

randcrack – Python random module cracker / predictor

Test PyPI PyPI - Python Version PyPI - Implementation

This script is able to predict python's random module random generated values.

Script is tested against Python versions from 3.9 to 3.13. Should work against other versions of CPython as well, since the underlying Mersenne Twister generator has not changed. Enjoy!

Installation

To install randcrack, simply:

$ pip install randcrack

How it works

The generator is based upon Mersenne Twister, which is able to generate numbers with excellent statistical properties(indistinguishable from truly random). However, this generator was not designed to be cryptographycally secure. You should NEVER use in critical applications as a PRNG for your crypto scheme. You can learn more about this generator on Wikipedia.

This cracker works as the following way. It obtains first 624 32 bit numbers from the generator and obtains the most likely state of Mersenne Twister matrix, which is the internal state. From this point generator should be synchronized with the cracker.

How to use

It is important to feed cracker exactly 32-bit integers generated by the generator due to the fact that they will be generated anyway, but dropped if you don't request for them. As well, you must feed the cracker exactly after new seed is presented, or after 624*32 bits are generated since every 624 32-bit numbers generator shifts it's state and cracker is designed to be fed from the begining of some state.

Implemented methods

Cracker has one method for feeding: submit(n). After submitting 624 integers it won't take any more and will be ready for predicting new numbers.

Cracker can predict new numbers with following methods, which work exactly the same as their siblings from the random module but without predict_ prefix. These are: predict_getrandbits, predict_randbelow, predict_randrange, predict_randint, predict_choice and predict_random

Here's an example usage:

import random, time
from randcrack import RandCrack

random.seed(time.time())

rc = RandCrack()

for i in range(624):
	rc.submit(random.getrandbits(32))
	# Could be filled with random.randint(0,4294967294) or random.randrange(0,4294967294)

print("Random result: {}\nCracker result: {}"
	.format(random.randrange(0, 4294967295), rc.predict_randrange(0, 4294967295)))

Output

Random result: 127160928
Cracker result: 127160928

As well as predicting future values, it can recover the previous states to predict earlier values, ones that came before the numbers you submit. After having submitted enough random numbers to clone the internal state (624), you can use the offset(n) method to offset the state by some number.

A positive number simply advances the RNG by n, as if you would ask for a number repeatedly n times. A negative number however will untwist the internal state (which can also be done manually with untwist()). Then after untwisting enough times it will set the internal state to exactly the point in the past where previous numbers were generated from. From then on, you can call the predict_*() methods again to get random numbers, now in the past.

import random, time
from randcrack import RandCrack

random.seed(time.time())

unknown = [random.getrandbits(32) for _ in range(10)]

cracker = RandCrack()

for _ in range(624):
	cracker.submit(random.getrandbits(32))

cracker.offset(-624)  # Go back -624 states from submitted numbers
cracker.offset(-10)   # Go back -10 states to the start of `unknown`

print("Unknown:", unknown)
print("Guesses:", [cracker.predict_getrandbits(32) for _ in range(10)])

Warning: The randint(), randrange() and choice() methods all use randbelow(n), which will internally may advance the state multiple times depending on the random number that comes from the generator. A number is generated with the number of bits n has, but it may still be above n the first time. In that case numbers keep being generated in this way until one is below n.

This causes predicting previous values of these functions to become imprecise as it is not yet known how many numbers were generated with the single function call. You will still be able to generate all the numbers if you offset back further than expected to include all numbers, but there will be an amount of numbers before/after the target sequence (e.g. if the sequence is [1, 2, 3], guesses may be [123, 42, 1, 2, 3, 1337]).

This is not a problem with the getrandbits() method, as it always does exactly 1. And the random() method always does exactly 2

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

randcrack-0.3.0.tar.gz (8.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

randcrack-0.3.0-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file randcrack-0.3.0.tar.gz.

File metadata

  • Download URL: randcrack-0.3.0.tar.gz
  • Upload date:
  • Size: 8.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for randcrack-0.3.0.tar.gz
Algorithm Hash digest
SHA256 0cc448b02fbe2ce16595fc53dc28e360d4d95f6a5817f8b1d3ea16b7d6f8490b
MD5 c1930a0084262e483da419045b8be512
BLAKE2b-256 91fb57f62efebe99d3856a711bbff6765222b482f2e5cd1a6818d6b7dd1c22e2

See more details on using hashes here.

File details

Details for the file randcrack-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: randcrack-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 7.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for randcrack-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 30b47e09889bcedd3109389b9f67b570db1ba33ef15774168252fbe6114573d5
MD5 4aa29c582724ff2712b0906e74782487
BLAKE2b-256 19322d38dfc4070765a37bd8f46d4814ccb1fb57953e7edda0245290a99ac71c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page