欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

可变长字节码算法

程序员文章站 2022-06-01 18:28:58
...
最近在看《大规模WEB服务开发技术》这本书中。书中提到“可变长字节码算法”的压缩数据的算法,以达到压缩数据,减少磁盘IO。
可变长字节码算法:
任意一个字节的最高位(下标7)均只作为标志位,而且根据字节所在位置需要乘以128的相应幂次;

这是他的伪代码
可变长字节码算法

仔细研究后,我翻译成PHP版的:

($n){
        $bytes = [];
        while (true){
            array_unshift($bytes, bcmod($n, 128));
            if($n 128){
                break;
            }else{
                $n = intval($n/128);
            }
        }
        $bytes[count($bytes) - 1] += 128;
        return $bytes;
    }

    function encode($numbers){
        $bytestream = [];
        foreach ($numbers as $n){
            $bytestream = array_merge($bytestream, codeNumber($n));
        }
        return $bytestream;
    }

    function decode($bytestream){
        $numbers = [];
        $n = 0;
        for ($i = 0; $i ($bytestream); $i++){
            if($bytestream[$i] 128){
                $n = 128 * $n + $bytestream[$i];
            }else{
                $n = 128 * $n + ($bytestream[$i] - 128);
                array_push($numbers, $n);
                $n = 0;
            }
        }
        return $numbers;
    }
    $a = encode([5, 130, 288]);
    var_dump($a);
    var_dump(decode($a));

打印出来的内容是:
array(5) { [0]=> int(133) [1]=> string(1)"1" [2]=> int(130) [3]=> string(1)"2" [4]=> int(160) }
array(3) { [0]=> int(5) [1]=> int(130) [2]=> int(288) }

    //写二进制
    $h = fopen('ejz3.txt', 'wb');
    foreach ($a as $k => $v)
    {
      $str3 =  pack('H*', sprintf("%02x", $v));
      fwrite($h,  $str3);
    }
    fclose($h);

    //读二进制
    $str2 = file_get_contents('ejz3.txt');
    $str2 = unpack("H*", $str2);
    $value = str_split($str2[1], 2);
    foreach ($value as $k => $v)
    {
      $value[$k] = base_convert($v, 16, 10);
    }