0

0

Huffman编码是什么?php中Huffman编码与解码的实现方法

不言

不言

发布时间:2018-07-26 15:37:32

|

2031人浏览过

|

来源于php中文网

原创

huffman编码是什么?huffman 编码是一种数据压缩算法。我们常用的 zip 压缩,其核心就是 huffman 编码,还有在 http/中,huffman 编码被用于 http 头部的压缩。这篇文章中我将给大家分享php中huffman编码与解码的实现方法。

1. Huffman编码

字数统计

Huffman编码的第一步就是要统计文档中每个字符出现的次数,PHP的内置函数 count_chars() 就可以做到:

$input = file_get_contents('input.txt');
$stat = count_chars($input, 1);

构造Huffman树

立即学习PHP免费学习笔记(深入)”;

接下来根据统计结果构造Huffman树,构造方法在 Wikipedia 有详细的描述。这里用PHP写了一个简易版的:

$huffmanTree = [];foreach ($stat as $char => $count) {
    $huffmanTree[] = [        
    'k' => chr($char),        
    'v' => $count,        
    'left' => null,        
    'right' => null,
    ];
}// 构造树的层级关系,思想见wiki:https://zh.wikipedia.org/wiki/%E9%9C%8D%E5%A4%AB%E6%9B%BC%E7%BC%96%E7%A0%81$size = count($huffmanTree);for ($i = 0; $i !== $size - 1; $i++) {
    uasort($huffmanTree, function ($a, $b) {        
    if ($a['v'] === $b['v'])
     {            
     return 0;
        }        
        return $a['v'] < $b['v'] ? -1 : 1;
    });
    $a = array_shift($huffmanTree);
    $b = array_shift($huffmanTree);
    $huffmanTree[] = [        
    'v' => $a['v'] + $b['v'],        
    'left' => $b,        
    'right' => $a,
    ];
}
$root = current($huffmanTree);

经过计算之后,$root 就会指向 Huffman 树的根节点

根据Huffman树生成编码字典

有了 Huffman 树,就可以生成用于编码的字典:

function buildDict($elem, $code = '', &$dict) {    
if (isset($elem['k']))
 {
        $dict[$elem['k']] = $code;
    } else {
        buildDict($elem['left'], $code.'0', $dict);
        buildDict($elem['right'], $code.'1', $dict);
    }
}
$dict = [];
buildDict($root, '', $dict);

写文件

运用字典将文件内容进行编码,并写入文件。将Huffman编码写入文件的有几个注意的地方:

将编码字典和编码内容一起写入文件后,就没法区分他们的边界了,因此需要在文件开始写入他们各自占用的字节数

PHP提供的 fwrite() 函数一次能写入 8-bit(一个字节)或者是 8的整数倍个bit。但Huffman编码中,一个字符可能只使用 1-bit 表示,PHP不支持只往文件中写入 1-bit 这种操作。所以需要我们自行对编码进行拼接,每凑齐 8-bit 才写入文件。

8470638-ba24d5e1aee7ce30.png

每凑齐8-bit才写入

与第二条类似,最终形成的文件大小一定是 8-bit 的整数倍。所以如果整个编码的大小是 8001-bit的话,还要在末尾补上 7个 0

$dictString = serialize($dict);// 写入字典和编码各自占用的字节数
$header = pack('VV', strlen($dictString), strlen($input));
fwrite($outFile, $header);// 写入字典本身
fwrite($outFile, $dictString);// 写入编码的内容$buffer = '';
$i = 0;while (isset($input[$i])) {
    $buffer .= $dict[$input[$i]];    
    while (isset($buffer[7])) {
        $char = bindec(substr($buffer, 0, 8));
        fwrite($outFile, chr($char));
        $buffer = substr($buffer, 8);
    }
    $i++;
}// 末尾的内容如果没有凑齐 8-bit,需要自行补齐
if (!empty($buffer))
 {
    $char = bindec(str_pad($buffer, 8, '0'));
    fwrite($outFile, chr($char));
}
fclose($outFile);

2.Huffman编码的解码

家电小商城网站源码1.0
家电小商城网站源码1.0

家电公司网站源码是一个以米拓为核心进行开发的家电商城网站模板,程序采用metinfo5.3.9 UTF8进行编码,软件包含完整栏目与数据。安装方法:解压上传到空间,访问域名进行安装,安装好后,到后台-安全与效率-数据备份还原,恢复好数据后到设置-基本信息和外观-电脑把网站名称什么的改为自己的即可。默认后台账号:admin 密码:132456注意:如本地测试中127.0.0.1无法正常使用,请换成l

下载

Huffman编码的解码相对简单:先读取编码字典,然后根据字典解码出原始字符。

解码过程有个问题需要注意:由于我们在编码过程中,在文件末尾补齐了几个0-bit,如果这些 0-bit 在字典中恰巧是某个字符的编码时,就会造成错误的解码。

所以解码过程中,当已解码的字符数达到文档长度时,就要停止解码。

3.试验

我们将Huffman编码Wiki页 的HTML代码保存到本地,进行Huffman编码测试,试验结果:

编码前: 418,504 字节

编码后: 280,127 字节

空间节省了 33%,如果原文的重复内容较多,Huffman编码节省的空间可以达到 50% 以上.

除了文本内容,我们再尝试将一个二进制文件进行Huffman编码,比如 f.lux的安装程序,试验结果如下:

编码前: 770,384 字节

编码后: 773,076 字节

编码后反而占用了更大的空间,一方面是由于我们存储字典时,并没有做额外的处理,占用了不少空间。另一方面,二进制文件中,各个字符出现的概率相对比较平均,无法发挥Huffman编码的优势。

相关推荐:

php对URL传参进行编码和解码解析

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

424

2023.08.14

http500解决方法
http500解决方法

http500解决方法有检查服务器日志、检查代码错误、检查服务器配置、检查文件和目录权限、检查资源不足、更新软件版本、重启服务器或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

438

2023.11.09

http请求415错误怎么解决
http请求415错误怎么解决

解决方法:1、检查请求头中的Content-Type;2、检查请求体中的数据格式;3、使用适当的编码格式;4、使用适当的请求方法;5、检查服务器端的支持情况。更多http请求415错误怎么解决的相关内容,可以阅读下面的文章。

423

2023.11.14

HTTP 503错误解决方法
HTTP 503错误解决方法

HTTP 503错误表示服务器暂时无法处理请求。想了解更多http错误代码的相关内容,可以阅读本专题下面的文章。

2552

2024.03.12

http与https有哪些区别
http与https有哪些区别

http与https的区别:1、协议安全性;2、连接方式;3、证书管理;4、连接状态;5、端口号;6、资源消耗;7、兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2239

2024.08.16

全国统一发票查询平台入口合集
全国统一发票查询平台入口合集

本专题整合了全国统一发票查询入口地址合集,阅读专题下面的文章了解更多详细入口。

17

2026.02.03

短剧入口地址汇总
短剧入口地址汇总

本专题整合了短剧app推荐平台,阅读专题下面的文章了解更多详细入口。

24

2026.02.03

植物大战僵尸版本入口地址汇总
植物大战僵尸版本入口地址汇总

本专题整合了植物大战僵尸版本入口地址汇总,前往文章中寻找想要的答案。

14

2026.02.03

c语言中/相关合集
c语言中/相关合集

本专题整合了c语言中/的用法、含义解释。阅读专题下面的文章了解更多详细内容。

2

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.2万人学习

手把手实现数据传输编码
手把手实现数据传输编码

共1课时 | 741人学习

PHP自制框架
PHP自制框架

共8课时 | 0.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号