Skip to content

Instantly share code, notes, and snippets.

@misablaha
Created July 1, 2013 09:45
Show Gist options
  • Save misablaha/5899613 to your computer and use it in GitHub Desktop.
Save misablaha/5899613 to your computer and use it in GitHub Desktop.
<?php
class Serializer
{
/**
* Vstupni pole musi obsahovat
* - pouze celociselne hodnoty
* - pro oznaceni klicu pismena a-f
*
* Pri oznaceni klicu pismeny a-f je vysledkem hexadecimal string
* ten lze prevest na binary string
* uspora mista v Redisu je pak cca 25%
*
* @param array $data
*
* @return string
* @throws \RuntimeException
*/
public static function pack( $data )
{
$res = '';
foreach ( $data as $key => $val ) {
// pro zaporna cisla nahradit minus nulou
if ( $val < 0 ) {
$val = '0' . ( $val * -1 );
}
$res .= $key . $val;
}
if ( preg_match( '~[^0-9a-f]~', $res ) > 0 ) {
throw new \RuntimeException( 'Unexpected data format.' );
}
// Pred retezec s lichym poctem znaku pridat nulu
if ( strlen( $res ) % 2 == 1 ) $res = '0' . $res;
return pack( 'H*', $res );
}
/**
* input: binary from "0a04b25c3d1371384703e1371384703f1371298342"
* output: array (
* a => -4,
* b => 25,
* c => 3,
* d => 1371384703,
* e => 1371384703,
* f => 1371298342
* }
*
* @param string $bin
*
* @return array
* @throws \RuntimeException
*/
public static function unpack( $bin )
{
$unpack = unpack( 'H*', $bin );
$unpack = $unpack[1];
// Odstranit uvodni nulu (doplnuje retezec na sudy pocet znaku)
if ( $unpack[0] === '0' ) $unpack = substr( $unpack, 1 );
$hits = preg_match_all( '~(\D+)(\d+)~', $unpack, $match );
// Musi byt alespon jedna shoda
if ( $hits == 0 ) {
throw new \RuntimeException( 'Unexpected data format.' );
}
$res = array_combine( $match[1], $match[2] );
foreach ( $res as &$val ) {
// Nula na zacatku hodnoty oznacuje zaporne cislo
$pos = ( $val[0] === '0' ) ? -1 : 1;
$val = intval( $val ) * $pos;
}
return $res;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment