Generate true random numbers in python

Question:

Python function that generates true random numbers?

By true random numbers it also means that what every time I run python the seed I generate is different. How do I do this?

Asked By: Ali Hassan

||

Answers:

There are many ways of generating random numbers, with exactly 1 thing in common – they all require external input. Let’s say you use a simple RNG like games use. The RNG takes an input (usually the system time, in seconds or milliseconds), and performs various wonky mathematical operations to produce a random-looking output.

Let’s say, however, that your computer has hardware that can measure atmospheric noise – you could fairly easily do that with your built-in microphone on any laptop, or an external mic on a desktop… Or you can measure the randomness of the user’s input – humans are known to be good sources of entropy… Or you could measure the decay of a subatomic particle – quantum mechanics is as random as it gets.

If you could do any of those things – and you can actually do all of them (#3 requires special hardware) you could pass those through a cryptographic hash (ex. SHA-256) to create a truly random stream of bytes with equal probability for every possible state. If you use SHA-256 it would be a good idea to hash at least 512 bits (64 bytes) of data if you want the most randomness possible.

Also, most modern systems have TRNGs (true random number generators) built into their CPUs; hardware manufacturers started doing this to address the need for better RNGs in cryptography. As such, many systems will default to a TRNG if one is available (using the python secrets module).

You can easily check if you have a TRNG on Linux by running cat /dev/random. If it stops and waits after a few seconds you don’t and need to use another technique. If if keeps going the same as /dev/urandom, you have a TRNG already and can make truly-random numbers easily!

Update:
The Python secrets module documentation can be found here.
A quick example program:

import secrets
low = 10
high = 100
out = secrets.randbelow(high - low) + low # out = random number from range [low, high)
print(out) # Print your number

You can also use secrets to create a hex string directly, or produce a stream of random bytes. You can see its docs to learn more.

Answered By: Serpent27

Python has nothing that allows you to generate "truly random" numbers, in the sense that they are uniformly distributed and independent of everything else (especially the latter).

In any case, the distinction between "pseudorandom" and "truly random" numbers is not what applications care about (and you didn’t really specify what kind of application you have in mind). Instead, in general:

  • Security applications care whether the numbers are hard to guess; in this case, only a cryptographic RNG can achieve this requirement (even one that relies on a pseudorandom number generator). A Python example is the secrets module or random.SystemRandom.
  • Scientific simulations care whether the numbers behave like independent uniform random numbers, and often care whether the numbers are reproducible at a later time. A Python example is numpy.random.Generator or random.Random.

See also these questions:

Answered By: Peter O.

There is a thing called true random numbers.
Check: www.random.org for more information.
Code example:

import requests
source = "https://www.random.org/integers/?num=1&min=1&max=100&col=5&base=10&format=plain&rnd=new"
number = requests.get(source)
number = int(number.text)
Answered By: Egon Kirchof

This will give you everything you need + how to set it & also how to get new seeds based on time:

def get_truly_random_seed_through_os(rand_size: int = 4) -> int:
    """
    Usually the best random sample you could get in any programming language is generated through the operating system. 
    In Python, you can use the os module.

    source: https://stackoverflow.com/questions/57416925/best-practices-for-generating-a-random-seeds-to-seed-pytorch/57416967#57416967
    """
    random_data = os.urandom(
        rand_size
    )  # Return a string of size random bytes suitable for cryptographic use.
    random_seed: int = int.from_bytes(random_data, byteorder="big")
    return int(random_seed)


def get_different_pseudo_random_seed_every_time_using_time() -> int:
    """ Get a different pseudo random seed every time using time."""
    import random
    import time

    # random.seed(int(time.time()))
    seed: int = int(time.time())
    return seed


def seed_everything(seed: int,
                    seed_torch: bool = True,
                    ):
    """
    https://stackoverflow.com/questions/57416925/best-practices-for-generating-a-random-seeds-to-seed-pytorch
    """
    import random
    import numpy as np
    import os

    random.seed(seed)
    np.random.seed(seed)
    os.environ["PYTHONHASHSEED"] = str(seed)
    if seed_torch:
        import torch
        torch.manual_seed(seed)
        # makes convs deterministic: https://stackoverflow.com/a/66647424/1601580, torch.backends.cudnn.deterministic=True only applies to CUDA convolution operations, and nothing else. Therefore, no, it will not guarantee that your training process is deterministic
        torch.backends.cudnn.deterministic = True
        torch.backends.cudnn.benchmark = False
        # #torch.use_deterministic_algorithms(True) # do not uncomment
        # fully_deterministic: bool = uutils.torch_uu.make_code_deterministic(args.seed)

as mentioned this is an excellent resource: Can I generate authentic random number with python?

Answered By: Charlie Parker
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.