Created
July 1, 2013 09:45
-
-
Save misablaha/5899613 to your computer and use it in GitHub Desktop.
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 | |
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