Random byte string in Python
Question:
I have buf="x00xFFxFFxFFxFFx00"
How can I make the "xFFxFFxFFxFF"
randomized?
Answers:
from random import randint
rstr = ''.join( randint(0, 255) for i in range(4) )
Do you want the middle 4 bytes to be set to a random value?
buf = 'x00' + ''.join(chr(random.randint(0,255)) for _ in range(4)) + 'x00'
Simple:
import functools, random, operator
functools.reduce(operator.add, ('%c' % random.randint(0, 255) for i in range(4)))
>>> import os
>>> "x00"+os.urandom(4)+"x00"
'x00!xc0zKx00'
On POSIX platforms:
open("/dev/urandom","rb").read(4)
Use /dev/random
for better randomization.
bytearray(random.getrandbits(8) for _ in xrange(size))
Faster than other solutions but not cryptographically secure.
An alternative way to obtaining a secure random sequence of bytes could be to use the standard library secrets
module, available since Python 3.6.
Example, based on the given question:
import secrets
b"x00" + secrets.token_bytes(4) + b"x00"
More information can be found at:
https://docs.python.org/3/library/secrets.html
I like using numpy library for that.
import numpy as np
X_1KB = 1024
X_256KB = 256 * X_1KB
X_1MB = 1024 * 1024
X_4MB = 4 * X_1MB
X_32MB = 32 * X_1MB
X_64MB = 2 * X_32MB
X_128MB = X_1MB * 128
np.random.bytes( X_1MB )
This can be used to generate a string of random bytes (replace n
with the desired amount):
import random
random_bytes = bytes([random.randrange(0, 256) for _ in range(0, n)])
-or-
random_bytes = bytes([random.randint(0, 255) for _ in range(0, n)])
-or-
random_bytes = bytes([random.getrandbits(8) for _ in range(0, n)])
The answer to the specific question would then be:
import random
buf = b'x00' + bytes([random.randrange(0, 256) for _ in range(0, 4)]) + b'x00'
-or-
buf = b'x00' + bytes([random.randint(0, 255) for _ in range(0, 4)]) + b'x00'
-or-
buf = b'x00' + bytes([random.getrandbits(8) for _ in range(0, 4)]) + b'x00'
As others pointed out, this should not be used for cryptography, but for everything else it should be perfectly fine.
Python 3.9 adds a new random.randbytes
method. This method generates random bytes:
from random import randbytes
randbytes(4)
Output:
b'xf3xf5xf8x98'
Be careful though. It should be used only when you are not dealing with cryptography. As stated in the docs:
This method should not be used for generating security tokens. Use secrets.token_bytes()
instead.
I have buf="x00xFFxFFxFFxFFx00"
How can I make the "xFFxFFxFFxFF"
randomized?
from random import randint
rstr = ''.join( randint(0, 255) for i in range(4) )
Do you want the middle 4 bytes to be set to a random value?
buf = 'x00' + ''.join(chr(random.randint(0,255)) for _ in range(4)) + 'x00'
Simple:
import functools, random, operator
functools.reduce(operator.add, ('%c' % random.randint(0, 255) for i in range(4)))
>>> import os
>>> "x00"+os.urandom(4)+"x00"
'x00!xc0zKx00'
On POSIX platforms:
open("/dev/urandom","rb").read(4)
Use /dev/random
for better randomization.
bytearray(random.getrandbits(8) for _ in xrange(size))
Faster than other solutions but not cryptographically secure.
An alternative way to obtaining a secure random sequence of bytes could be to use the standard library secrets
module, available since Python 3.6.
Example, based on the given question:
import secrets
b"x00" + secrets.token_bytes(4) + b"x00"
More information can be found at:
https://docs.python.org/3/library/secrets.html
I like using numpy library for that.
import numpy as np
X_1KB = 1024
X_256KB = 256 * X_1KB
X_1MB = 1024 * 1024
X_4MB = 4 * X_1MB
X_32MB = 32 * X_1MB
X_64MB = 2 * X_32MB
X_128MB = X_1MB * 128
np.random.bytes( X_1MB )
This can be used to generate a string of random bytes (replace n
with the desired amount):
import random
random_bytes = bytes([random.randrange(0, 256) for _ in range(0, n)])
-or-
random_bytes = bytes([random.randint(0, 255) for _ in range(0, n)])
-or-
random_bytes = bytes([random.getrandbits(8) for _ in range(0, n)])
The answer to the specific question would then be:
import random
buf = b'x00' + bytes([random.randrange(0, 256) for _ in range(0, 4)]) + b'x00'
-or-
buf = b'x00' + bytes([random.randint(0, 255) for _ in range(0, 4)]) + b'x00'
-or-
buf = b'x00' + bytes([random.getrandbits(8) for _ in range(0, 4)]) + b'x00'
As others pointed out, this should not be used for cryptography, but for everything else it should be perfectly fine.
Python 3.9 adds a new random.randbytes
method. This method generates random bytes:
from random import randbytes
randbytes(4)
Output:
b'xf3xf5xf8x98'
Be careful though. It should be used only when you are not dealing with cryptography. As stated in the docs:
This method should not be used for generating security tokens. Use
secrets.token_bytes()
instead.