<?php
function snowflake_test( $maxIds = 100 )
{
$sequences = [ ] ;
$ids = [ ] ;
for ( $i = 0 ; $i < $maxIds ; $i ++ ) {
if ( ! isset ( $sequences [ $timestamp ] ) ) $sequences [ $timestamp ] = 0 ;
else
$sequences [ $timestamp ] ++;
$ids [ ] = snowflake( $timestamp , 0 , $sequences [ $timestamp ] ) ;
}
$lapses = 0 ;
foreach ( $ids as $i => $id ) {
if ( isset ( $ids [ $i + 1 ] ) && $ids [ $i + 1 ] <= $id ) { $lapses ++;
}
}
echo 'Generated ' . $count . ' IDs. It took ' . round ( $end - $start , 5 ) . 's, that\'s ' . floor ( $count / ( $end - $start ) ) . ' IDs/sec(don\'t take this seriously...)' . "\r \n " ; echo 'Found ' . $collisions . ' collisions(repeated IDs).' . "\r \n " ;
echo 'Found ' . $lapses . ' lapses(nextId <= currentId).' . "\r \n \r \n " ;
if ( $maxIds <= 100 )
}
function snowflake( $timestamp = null , $machine = 0 , $sequence = 0 )
{
if ( $timestamp === null )
$hi = ( int
) ( $timestamp / pow ( 2 , 10 ) ) ; $lo = ( int
) ( $timestamp * pow ( 2 , 22 ) ) ;
$lo = $lo | ( $machine << 12 ) | $sequence ;
$hex = pack ( 'N2' , $hi , $lo ) ; $unpacked = unpack ( 'H*' , $hex ) ;
$hexdec = [ '0' => 0 , '1' => 1 , '2' => 2 , '3' => 3 , '4' => 4 , '5' => 5 , '6' => 6 , '7' => 7 , '8' => 8 , '9' => 9 , 'a' => 10 , 'b' => 11 , 'c' => 12 , 'd' => 13 , 'e' => 14 , 'f' => 15 ] ;
$dec = 0 ;
for ( $i = strlen ( $unpacked [ 1 ] ) - 1 , $e = 1 ; $i >= 0 ; $i --, $e = bcmul ( $e , 16 ) ) { $factor = $hexdec [ $unpacked [ 1 ] [ $i ] ] ;
}
return ( string) $dec ;
}
snowflake_test( 100 ) ;
PD9waHAKCmZ1bmN0aW9uIHNub3dmbGFrZV90ZXN0KCRtYXhJZHMgPSAxMDApCnsKCSRzZXF1ZW5jZXMgPSBbXTsKCSRpZHMgPSBbXTsKCSRzdGFydCA9IG1pY3JvdGltZSh0cnVlKTsKCQoJZm9yICgkaSA9IDA7ICRpIDwgJG1heElkczsgJGkrKykgewoJCSR0aW1lc3RhbXAgPSBmbG9vcihmbG9vcihtaWNyb3RpbWUodHJ1ZSkgKiAxMDAwKSAtIDEzMjUzNzYwMDAwMDApOwoJCQoJCWlmICghaXNzZXQoJHNlcXVlbmNlc1skdGltZXN0YW1wXSkpCgkJCSRzZXF1ZW5jZXNbJHRpbWVzdGFtcF0gPSAwOwoJCWVsc2UKCQkJJHNlcXVlbmNlc1skdGltZXN0YW1wXSsrOwoJCQoJCSRpZHNbXSA9IHNub3dmbGFrZSgkdGltZXN0YW1wLCAwLCAkc2VxdWVuY2VzWyR0aW1lc3RhbXBdKTsKCX0KCSRlbmQgPSBtaWNyb3RpbWUodHJ1ZSk7CgkKCSRjb3VudCA9IGNvdW50KCRpZHMpOwoJCgkkY29sbGlzaW9ucyA9ICRjb3VudCAtIGNvdW50KGFycmF5X3VuaXF1ZSgkaWRzKSk7CgkkbGFwc2VzID0gMDsKCWZvcmVhY2ggKCRpZHMgYXMgJGkgPT4gJGlkKSB7CgkJaWYgKGlzc2V0KCRpZHNbJGkrMV0pICYmICRpZHNbJGkrMV0gPD0gJGlkKSB7CgkJCSRsYXBzZXMrKzsKCQl9Cgl9CgkKCWVjaG8gJ0dlbmVyYXRlZCAnIC4gJGNvdW50IC4gJyBJRHMuIEl0IHRvb2sgJyAuIHJvdW5kKCRlbmQgLSAkc3RhcnQsIDUpIC4gJ3MsIHRoYXRcJ3MgJyAuIGZsb29yKCRjb3VudC8oJGVuZCAtICRzdGFydCkpIC4gJyBJRHMvc2VjKGRvblwndCB0YWtlIHRoaXMgc2VyaW91c2x5Li4uKScgLiAiXHJcbiI7CgllY2hvICdGb3VuZCAnIC4gJGNvbGxpc2lvbnMgLiAnIGNvbGxpc2lvbnMocmVwZWF0ZWQgSURzKS4nIC4gIlxyXG4iOwoJZWNobyAnRm91bmQgJyAuICRsYXBzZXMgLiAnIGxhcHNlcyhuZXh0SWQgPD0gY3VycmVudElkKS4nIC4gIlxyXG5cclxuIjsKCWlmICgkbWF4SWRzIDw9IDEwMCkKCQlwcmludF9yKCRpZHMpOwp9CgpmdW5jdGlvbiBzbm93Zmxha2UoJHRpbWVzdGFtcCA9IG51bGwsICRtYWNoaW5lID0gMCwgJHNlcXVlbmNlID0gMCkKewoJaWYgKCR0aW1lc3RhbXAgPT09IG51bGwpCgkJJHRpbWVzdGFtcCA9IGZsb29yKGZsb29yKG1pY3JvdGltZSh0cnVlKSAqIDEwMDApIC0gMTMyNTM3NjAwMDAwMCk7CgkKICAgICRoaSA9IChpbnQpKCR0aW1lc3RhbXAgLyBwb3coMiwgMTApKTsKICAgICRsbyA9IChpbnQpKCR0aW1lc3RhbXAgKiBwb3coMiwgMjIpKTsKICAgIAogICAgJGxvID0gJGxvIHwgKCRtYWNoaW5lIDw8IDEyKSB8ICRzZXF1ZW5jZTsKICAgICRoZXggPSBwYWNrKCdOMicsICRoaSwgJGxvKTsKICAgICR1bnBhY2tlZCA9IHVucGFjaygnSConLCAkaGV4KTsKCQoJJGhleGRlYyA9IFsnMCcgPT4gMCwgJzEnID0+IDEsICcyJyA9PiAyLCAnMycgPT4gMywgJzQnID0+IDQsICc1JyA9PiA1LCAnNicgPT4gNiwgJzcnID0+IDcsICc4JyA9PiA4LCAnOScgPT4gOSwgJ2EnID0+IDEwLCAnYicgPT4gMTEsICdjJyA9PiAxMiwgJ2QnID0+IDEzLCAnZScgPT4gMTQsICdmJyA9PiAxNV07CgkkZGVjID0gMDsKCWZvciAoJGkgPSBzdHJsZW4oJHVucGFja2VkWzFdKSAtIDEsICRlID0gMTsgJGkgPj0gMDsgJGktLSwgJGUgPSBiY211bCgkZSwgMTYpKSB7CgkJJGZhY3RvciA9ICRoZXhkZWNbJHVucGFja2VkWzFdWyRpXV07CgkJJGRlYyA9IGJjYWRkKCRkZWMsIGJjbXVsKCRmYWN0b3IsICRlKSk7Cgl9CiAgICByZXR1cm4gKHN0cmluZykkZGVjOwp9Cgpzbm93Zmxha2VfdGVzdCgxMDApOw==