Skip to content

Instantly share code, notes, and snippets.

@sanchezzzhak
Created November 23, 2016 11:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sanchezzzhak/d0e2c3b74f7816286eb1c8fa1f355e85 to your computer and use it in GitHub Desktop.
Save sanchezzzhak/d0e2c3b74f7816286eb1c8fa1f355e85 to your computer and use it in GitHub Desktop.
mongo short id
<?php
class Base62 {
const CHARS_SYMBOLS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';
/**
* @param $id
* @return string
*/
public static function encode($id){
$l = strlen(self::CHARS_SYMBOLS);
$chars = self::CHARS_SYMBOLS;
$hash='';
while($id > 0) {
$i = fmod($id,$l);
$hash= ($chars[intval($i)]) . $hash;
$id=floor($id/$l);
}
return $hash;
}
/**
* @param $code
* @return string
*/
public static function decode($code)
{
$l = strlen(self::CHARS_SYMBOLS);
$id=0;
$arr = array_flip(str_split(self::CHARS_SYMBOLS));
for($i=0,$len = strlen($code); $i < $len; ++$i) {
$id += $arr[$code[$i]] * pow($l, $len-$i-1);
}
return (string)$id;
}
}
class MongoIdShort
{
/*
a 4-byte timestamp,
a 3-byte machine identifier,
a 2-byte process id, and
a 3-byte counter.
*/
public static function encode($id)
{
$timestamp = hexdec(substr($id,0,8));
$identifier = hexdec(substr($id,8,6));
$pid = hexdec(substr($id,14,4));
$counter = hexdec(substr($id,18,6));
$hashsource = Base62::encode($timestamp) . Base62::encode($identifier) . '\\' . Base62::encode($pid) . '\\' . Base62::encode($counter);
return $hashsource;
}
public static function createMongoIdFromTimestamp($timestamp) {
$inc = 0;
$ts = pack('N', $timestamp);
$m = substr(md5(gethostname()), 0, 3);
$pid = pack('n', getmypid());
$trail = substr(pack('N', $inc++), 1, 3);
$bin = sprintf('%s%s%s%s', $ts, $m, $pid, $trail);
$id = '';
for ($i = 0; $i < 12; $i++) {
$id .= sprintf('%02X', ord($bin[$i]));
}
return new \MongoID($id);
}
public static function decode($id)
{
$part = explode('\\',$id);
$timestamp = Base62::decode(substr($part[0],0,6));
$identifier = Base62::decode(substr($part[0],6));
$pid = Base62::decode($part[1]);
$counter = Base62::decode($part[2]);
$len_identifier = strlen($identifier)-6;
$len_pid = strlen($pid)-4;
$len_counter = strlen($counter)-6;
return $hash = dechex($timestamp)
. ($len_identifier < 0 ? str_repeat('0',$len_identifier*-1) : '')
. dechex($identifier)
. ($len_pid < 0 ? str_repeat('0',$len_pid*-1) : '')
. dechex($pid)
. ($len_counter < 0 ? str_repeat('0',$len_counter*-1) : '')
. dechex($counter);
}
}
/***tests ***/
$ids = [
'5824736fcaec5460bbfdc489',
'58357bf59d1f9d381a000029',
'58357bf59d1f9d381a000030',
'58357bf59d1f9d381a005031',
'58357bf59d1f9d381a200033',
'58357bf59d1f9d381a001034',
strval( new MongoId()),
strval( new MongoId()),
strval( new MongoId()),
strval( new MongoId()),
strval( new MongoId()),
strval( new MongoId()),
strval( new MongoId()),
strval( new MongoId()),
strval( new MongoId()),
];
foreach($ids as $id){
echo "mongoId_source {$id} \n";
$encodeId = MongoIdShort::encode($id);
$decodeId = MongoIdShort::decode($encodeId);
$isTrue = $id == $decodeId;
echo "$id\n$encodeId\n{$isTrue}\n$decodeId\n========\n\n";
}
@sanchezzzhak
Copy link
Author

compress mongoid 25%-40%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment