Home > Net >  how do i use bits insted of bytes in (os.urandom(32)
how do i use bits insted of bytes in (os.urandom(32)

Time:07-09

I am writing an experimental code that generates random tokens using os.urandom, I was wondering how do I generate a 66 bit random token.? 66 bit is 8.25 bytes and it does not take floating numbers. I specifically need 66 bit how do i do it?

CodePudding user response:

  • simple solution: you get three 32-bit random values (os.urandom(96)), and simply ignore 30 bits of the last 32 bits you get
  • better solution: you get a 33 random 32-bit values, put them in a buffer, take the lowest 66 bit (using bitwise operations, &), and then shift your index into the buffer. For the next random value, you take the next 66 bit from your buffer through bitwise operations.

Also make sure you actually need all your randomness to come from the operating system. This is usually not the case. In most practical applications, you seed your pseudo-random number generator once with random values from your OS, and then have a very cheap way of generating sufficiently random/secure random numbers. It depends on what you build!

But especially for things like session tokens, you don't need incredibly cryptographically secure values - take a (properly) seeded PRNG, get sufficiently many bits, append a secret salt to the end, run a SHA-256 hash on it, get a session token that cannot be guessed, and knowledge of one would not allow you to infer any other valid tokens.

CodePudding user response:

You can generate 9 bytes and take the first 66 bits using a bitmask operation. on the last byte.

Here's a beautiful one liner:

"".join([bin(c).replace("0b", "").zfill(8) for c in us.urandom(9)])[:-6]

This will generate 9 bytes of random as a byte string, them iterate the 9 bytes in the byte string, convert each one into a binary string notation (i.e. 0b110001, remove the 0b from the front, zero pad where needed, join into a single string and strip the excess 6 bits from the end. convert ever

CodePudding user response:

You can use this code (you get list of 66 ints in range 0-1)

i = int.from_bytes(os.urandom(9), 'little')
bits = [(i >> s) & 1 for s in range(66)]

CodePudding user response:

You could look at the secrets module - specifically the .randbits method. (From the looks of it - other methods there might also be useful...)

eg:

import secrets

for n in range(5):
    # get an integer from the result of 66 random bits
    bits = secrets.randbits(66)
    # do something with it... just printing it here and in hex form...
    print(f'{bits} -> {bits:x}')

(my output:)

54559484978661254443 -> 2f52a3a85015d652b
72193567388919391240 -> 3e9e3130ad4c3e408
11844854214081132530 -> a4616026a69837f2
7354217677416448887 -> 660f6e03674e4377
72513338622329697030 -> 3ee532148ed933306
  • Related