varint算法——本质上是牺牲最高位作为标识数据结束位,达到变长编码,说白了就是贪心的分割位
varint算法,摘自:http://blog.csdn.net/liaoquesg/article/details/50897327
最近在看《大规模WEB服务开发技术》这本书中。书中提到“可变长字节码算法”的压缩数据的算法,以达到压缩数据,减少磁盘IO。
可变长字节码算法:
任意一个字节的最高位(下标7)均只作为标志位,而且根据字节所在位置需要乘以128的相应幂次;(我觉得这个算法只能用作自然数的压缩)
这是他的伪代码
仔细研究后,我翻译成PHP版的:
<?php function codeNumber($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 < count($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); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」