Skip to content

Instantly share code, notes, and snippets.

@tanakahisateru
Created November 21, 2019 19:05
Show Gist options
  • Save tanakahisateru/ff65a6b572356fe3be3570e0d8977feb to your computer and use it in GitHub Desktop.
Save tanakahisateru/ff65a6b572356fe3be3570e0d8977feb to your computer and use it in GitHub Desktop.
NEVER USE this UUIDv4 generator
#!/usr/bin/env php
<?php
/**
* Try: bin/genuuid4.php 65536 | sort | uniq -d
*/
class UuidV4
{
const VERSION = 4;
const VARIANT = 2;
/**
* @return string
*/
public static function generate(): string
{
// 128 bit random bytes sequence by ASCII string
$bytes = static::random16Bytes();
// Text formatted UUIDv4
// random 122 bits (6 bit reserved)
return static::fromBytes($bytes);
}
protected static function fromBytes(string $bytes): string
{
assert(strlen($bytes) >= 16);
return
// 32 bit random
bin2hex(substr($bytes, 0, 4)) .
'-' .
// 16 bit random
bin2hex(substr($bytes, 4, 2)) .
'-' .
// 4 bit version + 12 bit random
base_convert(
(self::VERSION << 4) | 0b00001111 & ord(substr($bytes, 6, 1)),
10,
16
) . bin2hex(substr($bytes, 7, 1)) .
'-' .
// 2 bit variant + 14 bit random
base_convert(
(self::VARIANT << 6) | 0x00111111 & ord(substr($bytes, 8, 1)),
10,
16
) . bin2hex(substr($bytes, 9, 1)) .
'-' .
// 48 bit random
bin2hex(substr($bytes, 10, 6));
}
protected static function random16Bytes(): string
{
// 16 bit * 8 --> 16 bytes
$bytes = "";
for ($i = 0; $i < 8; $i++) {
$v = mt_rand(0, 0xffff);
$bytes .= chr($v & 0xff00 >> 8);
$bytes .= chr($v & 0x00ff);
}
return $bytes;
}
}
$repeats = $argc > 1 ? intval($argv[1]) : 1;
for ($i = 0; $i < $repeats; $i++) {
srand(random_int(0, PHP_INT_MAX));
echo UuidV4::generate() . "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment