74

I have buf="\x00\xFF\xFF\xFF\xFF\x00"

How can I make the "\xFF\xFF\xFF\xFF" randomized?

0

10 Answers 10

90
>>> import os
>>> "\x00"+os.urandom(4)+"\x00"
'\x00!\xc0zK\x00'
Sign up to request clarification or add additional context in comments.

7 Comments

i just check the python doc.. whats different with ''.join(chr(random.randint(0,255)) for _ in range(4))
@zack, apart from being more efficent, randint returns pseudo-random numbers. urandom returns random bytes that are suitable for cryptographic use
@JohnLaRooy Unless /dev/urandom is using some hardware random number generator, its numbers are also pseudo-random. A deterministic machine will always generate pseudo-random numbers.
@NullUserException, see urandomhere /dev/random is a more random source of randomness, but blocks whenever there is not enough entropy.
@NullUserException On Linux, /dev/random uses known sources of entropy as input, including (but not limited to) human users's movements of the mouse, environmental noise, etc. Although the kernel in and of itself is deterministic, the combination kernel+human+environment is not.
|
41

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

Comments

31

Python 3.9 adds a new random.randbytes method. This method generates random bytes:

from random import randbytes

randbytes(4)

Output:

b'\xf3\xf5\xf8\x98'

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.

2 Comments

One cool thing about this is that allows setting a seed for deterministic testing with random.seed: stackoverflow.com/questions/32329381/…
FYI, if you don't have Python 3.9, randbytes is literally implemented as random.getrandbits(n * 8).to_bytes(n, 'little')
29
bytearray(random.getrandbits(8) for _ in xrange(size))

Faster than other solutions but not cryptographically secure.

Comments

8

On POSIX platforms:

open("/dev/urandom","rb").read(4)

Use /dev/random for better randomization.

3 Comments

in practice, this is about 2.5 times faster than os.urandom if you leave the file descriptor open between calls. useful for random guesses at nonces for cryptocurrency hashes.
@jcomeau_ictx Why would you use os.urandom if you don't need it to be cryptographically secure - there are much faster prng's than os.urandom.
@user3467349 To be fair, urandom is potentially truly random and not only PRNG
7

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'

Comments

6

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.

Comments

5

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 )

Comments

1

Simple:

import functools, random, operator
functools.reduce(operator.add, ('%c' % random.randint(0, 255) for i in range(4)))

2 Comments

That will return a string representation of a list, not a string as the OP asked.
"".join(...) is the preferred way to turn a sequence into a string
-2
from random import randint 
rstr = ''.join( randint(0, 255) for i in range(4) )

3 Comments

NameError: name 'buf' is not defined
Comment by anonymous user: You can't join anything but a list of strings into a string so change the int to string character. Code: rstr = "".join( chr(randint(0, 255)) for i in range(4)).
Typical example of a poor answer. No explanation of functionality, of your code, or of reasons why this solution is effective. I did not vote you down, but I can see why others did. However, you are not alone, it seems many do this and I feel it reduces the quality of SO.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.