1

I want to make a random number generator

So i did a lot of research and made a small code below

a=1
b=2
m=5000
x=3
lst=[]
for i in range(10):
  x=(a*x+b)%m
  lst.append(x)
print(lst)
if len(lst) != len(set(lst)):
    print("it has duplicates but possibly random numbers")
else:
    print("those were random numbers")

The mathematical equation I got from here It gives me some random number but only when the values are big, if i chose small values(Suppose m=5,keeping rest of the values same) i can see a repeated number series is getting formed.

* Question*

I can see from here python gets it from OS it doesn't generate them So is it the correct way to generate random number in python ??

user7422128
  • 902
  • 4
  • 17
  • 41

2 Answers2

2

I am only covering non cryptographically secure pseudorandom number generator

A PRNG is a function that returns apparently random(fake randomness) numbers that are good enough to trick humans. There is a pattern, it is just a hard pattern(for us)

For example:

The following sequence is pretty straightforward(I'd say if it was generated by a PRNG, it is a really bad PRNG)

[0, 2, 4, 6, 8]

Now, I'd say this other sequence was generated by a better PRNG

[1, 5, 5, 2, 6, 0, 3]

So, we want a function that generates a sequence with a hard pattern(for humans), and each number is dependent on the previous number.

A good approach could be to use a bunch of logical & arithmetic operations(e.g. XOR, Division, OR, subtraction, modulus)

I wrote this function doing exactly what I described above and the results for me are pretty satisfactory.

n = 0xDEADBEEF
#returns a pseudorandom number between 0-9
def random():
    global n
    n = (n * 63) % 0xC4CB7296
    n = n ^ 0x1754FBF
    n = (n*0xFF) % 4294967296
    n = n ^ 0x222F42CB
    n = n | 0x1234567890
    n = ((n + 14351514) * 32) % 7777333
    return n % 10

for i in range(6):
    print(random())

#Outputs:
2
4
7
2
6
9

If you don't always want the same results you could use a seed:

def seed(s):
    global n
    n = s


seed(12345)

for i in range(6):
    print(random())

#Outputs
9
1
5
8
5
9
Blastosphere
  • 351
  • 2
  • 9
0

Your random is allmost correct. Problem lies in your range generator:

The period of a general mixed congruential generator is at most m, and for some choices of factor a much less than that.

So if your m=5 - range should not be more than 5.

Also, note, that:

The mixed congruential generator will have a full period for all seed values if and only if:

m and the offset c are relatively prime,
a-1 is divisible by all prime factors of m,
a-1 is divisible by 4 if m is divisible by 4.

Source: wiki article provided by you

Yaroslav Surzhikov
  • 1,568
  • 1
  • 11
  • 16