经典加解密算法——香农算法介绍(附源码!)

简介: 经典加解密算法——香农算法介绍(附源码!)

概述


香农算法(Shannon-Fano 编码)是克劳德·香农在1948年发表的《A Mathematical Theory of Communication》中提出的一种基于数据统计的无损压缩编码算法。该算法主要通过计算不同字符在原始数据中出现的频率,并基于这些频率为每个字符分配一个唯一的编码来实现无损压缩。


编码过程


香农算法的编码过程如下:


统计字符出现频率:


遍历原始数据记录所有不同字符出现的频率。


构建哈夫曼树:


将所有字符及其频率构成叶子节点,按频率大小把两个叶子节点合并为一个新节点,直到哈夫曼树的根节点为止。


遍历哈夫曼树,为每个叶子节点编号:


从根节点开始,深度优先遍历哈夫曼树,为每个叶子节点分配一个唯一的二进制编码,将左子树标记为0,右子树标记为1。


编码特点


香农算法的编码特点如下:


每个字符的编码是唯一的,并具有前缀码的特性——任何一个字符的编码都不是另一个字符编码的前缀,因此可以保证解码时不会产生歧义。


编码长度与字符出现频率有关,出现频率越高的字符,其对应的二进制编码越短。


香农算法可以实现无损压缩,即解压缩后可以完全恢复原始数据,但对于某些特定的数据集,其压缩率并不一定最优。


应用场景


香农算法在以下场景中得到了广泛应用:


文本压缩:对于较长的文本文件,通过香农算法进行压缩,可以减少文件的存储和传输成本。


图像压缩:基于JPEG2000标准的图像压缩算法就采用了香农算法。


信息论研究:香农算法是信息熵和信息熵编码的基础,可以为学者们提供更多探索信息理论领域的思路。


缺点


香农算法虽然可以实现无损压缩,但存在以下缺点:


无法动态适应:由于编码表是事先生成的,因此当输入的数据集发生变化时,需要重新生成编码表。


压缩率不一定最优:尽管香农算法可以实现无损压缩,但对于某些特定的数据集,其压缩率并不一定最优。因此,在实际应用中,需要针对数据集和应用场景进行选择。


综述


香农算法是一种经典的无损压缩算法,已经被广泛应用于文本压缩、图像压缩以及信息论研究等领域。虽然香农算法有着自身的缺点,但它的编码过程简洁易懂,具有较高的逻辑性和实用性,能够为小白用户提供压缩数据的一种思路。


香农算法python源码

import numpy as np
def buildCodeTable(codeTable, cumProb, index, code):
    if index > len(codeTable):
        return codeTable
    if cumProb[index-1] <= 0.5:
        codeTable[index-1][1] = code + '0'+' '
        codeTable = buildCodeTable(codeTable, cumProb, index+1, code+'0')
    else:
        codeTable[index-1][1] = code + '1'+' '
        codeTable = buildCodeTable(codeTable, cumProb, index+1, code+'1')
    return codeTable
def shannonCoding(text):
# 计算字符频率
    symbols = list(set(text))
    freq = [(text.count(s) + 1) / (len(text) + len(set(text))) for s in symbols]
        # 计算累积概率
    cumProb = np.cumsum(freq)
    # 输出中间结果,调试用
    print('symbols:', symbols)
    print('freq:', freq)
    print('cumProb:', cumProb)
    # 构建编码表
    codeTable = [[symbols[i], ''] for i in range(len(symbols))]
    codeTable = buildCodeTable(codeTable, cumProb, 1, '')
    # 输出编码表,调试用
    print('codeTable:', codeTable)
    # 编码
    encoded = ''.join([codeTable[symbols.index(s)][1] for s in text])
    # 解码
    decoded = ''
    code = ''
    for b in encoded:
        code += b
        i = -1
        for j, c in enumerate(codeTable):
            if c[1] == code:
                i = j
                break
        if i >= 0:
            decoded += codeTable[i][0]
            code = ''
    # 计算平均码长
    codeLengths = [len(c[1]) for c in codeTable]
    avgCodeLength = sum([c * f for c, f in zip(codeLengths, freq)])
    # 计算编码效率
    efficiency = 1 / avgCodeLength
    return encoded, decoded, avgCodeLength, efficiency,codeTable
text = 'hello world'
encoded, decoded, avgCodeLength, efficiency,codeTable = shannonCoding(text)
print('编码结果:')
print(encoded)
print('解码结果:')
print(decoded)
print('平均码长:')
print(avgCodeLength)
print('编码效率:')
print(efficiency)
print('编码表:')
print(codeTable)
相关文章
|
2月前
|
算法 数据可视化 数据挖掘
基于EM期望最大化算法的GMM参数估计与三维数据分类系统python源码
本内容展示了基于EM算法的高斯混合模型(GMM)聚类实现,包含完整Python代码、运行效果图及理论解析。程序使用三维数据进行演示,涵盖误差计算、模型参数更新、结果可视化等关键步骤,并附有详细注释与操作视频,适合学习EM算法与GMM模型的原理及应用。
|
6月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
搜索推荐 算法 小程序
基于Java协同过滤算法的电影推荐系统设计和实现(源码+LW+调试文档+讲解等)
基于Java协同过滤算法的电影推荐系统设计和实现(源码+LW+调试文档+讲解等)
|
7月前
|
机器学习/深度学习 自然语言处理 算法
生成式 AI 大语言模型(LLMs)核心算法及源码解析:预训练篇
生成式 AI 大语言模型(LLMs)核心算法及源码解析:预训练篇
1097 0
|
9月前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
649 5
|
搜索推荐 算法 小程序
基于Java协同过滤算法的图书推荐系统设计和实现(源码+LW+调试文档+讲解等)
基于Java协同过滤算法的图书推荐系统设计和实现(源码+LW+调试文档+讲解等)
|
机器学习/深度学习 算法 PyTorch
【从零开始学习深度学习】38. Pytorch实战案例:梯度下降、随机梯度下降、小批量随机梯度下降3种优化算法对比【含数据集与源码】
【从零开始学习深度学习】38. Pytorch实战案例:梯度下降、随机梯度下降、小批量随机梯度下降3种优化算法对比【含数据集与源码】
|
10月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
342 7
|
10月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
383 8
|
11月前
|
存储 算法 安全
ArrayList简介及使用全方位手把手教学(带源码),用ArrayList实现洗牌算法,3个人轮流拿牌(带全部源码)
文章全面介绍了Java中ArrayList的使用方法,包括其构造方法、常见操作、遍历方式、扩容机制,并展示了如何使用ArrayList实现洗牌算法的实例。
103 1

热门文章

最新文章