"""
Random byte sequence generation utilities.
This module provides helper functionality for generating random byte sequences
with configurable length, control over the inclusion of zero bytes, and support
for custom random number generators.
The module exposes the following public function:
* :func:`random_bytes` - Generate random bytes with configurable parameters.
.. note::
The implementation does not validate the ``length`` argument. Supplying a
negative value results in an empty byte sequence because of Python's
``range`` semantics.
Example::
>>> from hbutils.random.binary import random_bytes
>>> random_bytes(8)
b'\\x93\\x1f\\xd2\\x8e\\x12\\xa7\\x4c\\xf0'
>>> random_bytes(4, allow_zero=True)
b'\\x00\\x7a\\x19\\xff'
"""
import random
from random import _inst as _DEFAULT_RANDOM
from typing import Optional
__all__ = [
'random_bytes',
]
[docs]
def random_bytes(length: int = 32, allow_zero: bool = False, rnd: Optional[random.Random] = None) -> bytes:
r"""
Generate random bytes with customizable options.
This function generates a sequence of random bytes with the specified length.
You can control whether the generated bytes may include ``0x00`` values and
optionally provide a custom :class:`random.Random` instance to drive the
randomness.
:param length: Length of the byte sequence to generate, defaults to ``32``.
:type length: int
:param allow_zero: Whether to allow ``0x00`` to appear in the result. If
``False``, only bytes from ``0x01`` to ``0xFF`` will be generated.
Defaults to ``False``.
:type allow_zero: bool
:param rnd: Random object to use for generation. If ``None``, the default
system random number generator is used.
:type rnd: Optional[random.Random]
:return: A sequence of random bytes with the specified length.
:rtype: bytes
Example::
>>> from hbutils.random.binary import random_bytes
>>> random_bytes()
b'\\xdc\\xdc$\\x05\\x83\\x04\\x812\\xfd\\xda^\\x7f[{\\xbc\\x99\\x88*\\xab3\\x87}\\xd1\\xab\\xddc\\xa2p\\xb2\\xcb\\x07\\xc5'
>>> random_bytes(64)
b"i7\\x98\\xd5\\x81\\x1d\\xdb\\xd8\\xe1^\\xf2\\xe4\\xbf\\xe0O^\\xeb\\xed\\xb0i\\xaa\\xf3\\x16Jx\\xf7J\\xd7\\xae1\\x81\\xc6\\xad\\xd21\\x15\\x8aX\\xb6\\xc7\\x85\\xa4\\x1c{\\xac^6\\xdf\\x03\\x94kR}\\x91\\x96\\xfe\\x06{'I\\xed5\\x03r"
>>> random_bytes(16, allow_zero=True) # May contain 0x00 bytes
b'\\x00\\x45\\x8a\\x00\\xf3\\x12\\x67\\x00\\xab\\xcd\\xef\\x00\\x11\\x22\\x33\\x44'
"""
rnd = rnd or _DEFAULT_RANDOM
bits = []
for i in range(length):
if allow_zero:
bits.append(rnd.randint(0, 0xff))
else:
bits.append(rnd.randint(1, 0xff))
return bytes(bits)