function ByteString::fromRandom
File
-
vendor/
symfony/ string/ ByteString.php, line 46
Class
- ByteString
- Represents a binary-safe string of bytes.
Namespace
Symfony\Component\StringCode
public static function fromRandom(int $length = 16, ?string $alphabet = null) : self {
if ($length <= 0) {
throw new InvalidArgumentException(\sprintf('A strictly positive length is expected, "%d" given.', $length));
}
$alphabet ??= self::ALPHABET_ALPHANUMERIC;
$alphabetSize = \strlen($alphabet);
$bits = (int) ceil(log($alphabetSize, 2.0));
if ($bits <= 0 || $bits > 56) {
throw new InvalidArgumentException('The length of the alphabet must in the [2^1, 2^56] range.');
}
if (\PHP_VERSION_ID >= 80300) {
return new static((new Randomizer())->getBytesFromString($alphabet, $length));
}
$ret = '';
while ($length > 0) {
$urandomLength = (int) ceil(2 * $length * $bits / 8.0);
$data = random_bytes($urandomLength);
$unpackedData = 0;
$unpackedBits = 0;
for ($i = 0; $i < $urandomLength && $length > 0; ++$i) {
// Unpack 8 bits
$unpackedData = $unpackedData << 8 | \ord($data[$i]);
$unpackedBits += 8;
// While we have enough bits to select a character from the alphabet, keep
// consuming the random data
for (; $unpackedBits >= $bits && $length > 0; $unpackedBits -= $bits) {
$index = $unpackedData & (1 << $bits) - 1;
$unpackedData >>= $bits;
// Unfortunately, the alphabet size is not necessarily a power of two.
// Worst case, it is 2^k + 1, which means we need (k+1) bits and we
// have around a 50% chance of missing as k gets larger
if ($index < $alphabetSize) {
$ret .= $alphabet[$index];
--$length;
}
}
}
}
return new static($ret);
}