from __future__ import annotations import random import secrets CONFUSE_CHARS = 'OoIl01' def make_rng(seed: int | None=None) -> tuple[random.Random, int]: if seed is None: seed = secrets.randbits(63) return (random.Random(seed), seed) def gen_name(rng: random.Random, length: int | None=None, used: set[str] | None=None) -> str: if length is None: length = rng.randint(12, 20) used = used or set() for _ in range(64): name = '_' + ''.join((rng.choice(CONFUSE_CHARS) for _ in range(length))) if name not in used: return name while True: name = '_' + ''.join((rng.choice(CONFUSE_CHARS) for _ in range(length + rng.randint(1, 4)))) if name not in used: return name def gen_bytes(rng: random.Random, length: int) -> bytes: return bytes((rng.randrange(256) for _ in range(length)))