Created
March 15, 2023 21:46
-
-
Save ranaroussi/ec91bc1eec21703f7e7cf78ff748425f to your computer and use it in GitHub Desktop.
Simple PHP implementation of Nanoid, secure URL-friendly unique ID generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Generate secure URL-friendly unique ID. | |
* By default, ID will have 21 symbols to have same collisions probability | |
* as UUID v4. | |
* | |
* @param integer $len The length of the ID to generate. | |
* @param mixed $entropy balanced, true (max), false (min) | |
* @param string $alphabet The characters to use in the ID. | |
* | |
* @return string random string of characters | |
*/ | |
function generateNanoId(int $len = 21, mixed $entropy = 'balanced', string $alphabet = '_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'): string | |
{ | |
$id = ''; | |
$alphabet_len = strlen($alphabet); | |
if ($entropy === false || $entropy == 'balanced') { | |
$tolen = $entropy == 'balanced' ? $len / 2 : $len; | |
for ($i = 0; $i < $tolen; $i++) { | |
$id .= $alphabet[random_int(0, $alphabet_len - 1)]; | |
} | |
if ($entropy != 'balanced') { | |
return $id; | |
} | |
} | |
$mask = (2 << (int) (log($alphabet_len - 1) / M_LN2)) - 1; | |
$step = (int) ceil(1.6 * $mask * $len / $alphabet_len); | |
while (true) { | |
$bytes = unpack('C*', random_bytes($len)); | |
for ($i = 1; $i <= $step; $i++) { | |
$byte = $bytes[$i]&$mask; | |
if (isset($alphabet[$byte])) { | |
$id .= $alphabet[$byte]; | |
if (strlen($id) === $len) { | |
return $id; | |
} | |
} | |
} | |
} | |
} | |
// usage: | |
$nanoId = generateNanoId(); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment