跳转到主要内容

libRaptorQ的Python CFFI绑定(RaptorQ RFC6330 FEC实现)。

项目描述

Python 2.X CFFI绑定libRaptorQ v0.1.x - C++11实现的RaptorQ前向纠错码,如RFC6330中所述。

警告:正确使用libRaptorQ RFC6330 API(该模块围绕其包装)需要了解RFC中描述的一些概念和参数,不正确使用可能会导致无法解码的数据!有关更多详细信息,请参阅下面的“使用”部分。

警告:据我所知(我不是律师),关于这项技术的专利很多,这对于任何高调的商业项目来说可能很重要,尤其是在美国和加拿大。


一般信息

引用维基百科关于Raptor码

像泉码一样,Raptor码将包含k个符号的消息编码成一系列可能的无限编码符号,只要知道任何k个或更多的编码符号,就有一定的概率可以恢复消息。

Raptor码(“RAPid TORnado”)是已知的第一种具有线性时间编码和解码的泉码类别。

并且 RFC6330

RaptorQ码是一种新的码族,它比RFC 5053中的Raptor码提供了更好的灵活性、支持更大的源块大小和更好的编码效率。

…在大多数情况下,一个与源符号数量相等的集合是足够的;在极少数情况下,需要稍微多于源符号数量的集合。

实际上这意味着,源数据块大小为1 MiB(例如),可以从接收到的任何1.002 MiB的符号中(来自“Application Layer Forward Error Correction for Mobile Multimedia Broadcasting Case Study”论文)以非常高的概率恢复。

请注意,作为一个概率算法,RaptorQ可能会有极不可能的病态情况,并且可以通过这些情况被利用,例如通过删除特定的数据块(有关更多详情,请参阅“Stopping a Rapid Tornado with a Puff”论文)。

编码数据将与原始数据加上“修复符号”的大小大致相同,即几乎没有大小开销,除了故意生成的部分。

使用方法

模块包含命令行脚本(“rq”,在安装或作为存储库中的符号链接时),其中包含编码和解码的示例代码,可以作为独立工具使用,或用于基本算法测试/展示。

也可以通过命令行使用,通过python2 -m libraptorq ...调用(当作为模块安装时),例如python2 -m libraptorq --help

重要:在当前的0.1.x libRaptorQ API中,指定不合适的编码参数,例如在编码200K+的数据时,将symbol_size设置为16和max_memory设置为200,将会无声地产生无法解码的编码数据。

命令行脚本

要编码文件,增加50%的额外符号(结果是不可分割的数据块需要完整存储/传输或完全丢失)和从这些中(所需的K个符号+X个修复符号)的30%被丢弃(仅用于测试目的)后保存到“setup.py.enc”

% ./rq --debug encode -s16 -m200 --repair-symbols-rate 0.5 --drop-rate 0.3 setup.py setup.py.enc
Initialized RQEncoder (0.063s)...
Precomputed blocks (0.002s)...
Finished encoding symbols (9 blocks, 0.008s)...
Closed RQEncoder (0.002s)...
Encoded 1,721 B into 167 symbols (needed: >108, repair rate: 50%),
  45 dropped (30%), 122 left in output (1,952 B without ids)

从这些中解码原始文件

% ./rq --debug decode setup.py.enc setup.py.dec
Initialized RQDecoder (0.064s)...
Decoded enough symbols to recover data (0.010s)...
Closed RQDecoder (0.002s)...
Decoded 1,721 B of data from 108 processed symbols (1,728 B without ids, symbols total: 122)

% sha256sum -b setup.py{,.dec}
36c50348459b51821a2715b0f5c4ef08647d66f77a29913121af4f0f4dfef454 *setup.py
36c50348459b51821a2715b0f5c4ef08647d66f77a29913121af4f0f4dfef454 *setup.py.dec

无论丢弃哪些块(由random.choice选取),只要每个“块”中剩余的块的数量略高(大约高0.02%)于K,文件都可以从输出中恢复。

脚本输出数据(例如“setup.py.enc”)是JSON编码的base64编码的符号列表,以及一些用于lib初始化(oti_schemeoti_common)的参数。输入数据长度和源数据的sha256哈希,以确保解码数据与原始数据相同(否则退出错误)。

使用–help选项查看所有其他脚本参数。

Python模块

用作python2模块

from libraptorq import RQEncoder

data = 'some input string' * 500

# Data size must be divisible by RQEncoder.data_size_div
data_len, n = len(data), RQEncoder.data_size_div
if data_len % n: data += '\0' * (n - data_len % n)

with RQEncoder(data, min_subsymbol_size=4, symbol_size=16, max_memory=200) as enc:

  symbols = dict()
  oti_scheme, oti_common = enc.oti_scheme, enc.oti_common

  for block in enc:
    symbols.update(block.encode_iter(repair_rate=0))

data_encoded = data_len, oti_scheme, oti_common, symbols

oti_schemeoti_common是两个整数,指定编码器选项,需要初始化解码器,可以在两端硬编码(如果为常量)。

block.encode_iter()可以无选项使用,以产生最大可能的符号量,最多达到block.symbols + block.max_repair。上面的例子仅产生K个符号 - 最小所需量。

对于解码(反向操作)

from libraptorq import RQDecoder

data_len, oti_scheme, oti_common, symbols = data_encoded

with RQDecoder(oti_common, oti_scheme) as dec:
  for sym_id, sym in symbols.viewitems(): dec.add_symbol(sym, sym_id)

  data = dec.decode()[:data_len]

请注意,在实际应用中,例如在传输UDP数据包中的每个符号时,您可能需要发送类似于 sym_id || sym_data || checksum 的内容,并从 block.encode_iter() 中持续发送这些内容,直到对方确认它可以解码一个数据块(即接收到了足够的符号,见 RQDecoder.decode_block()),然后以类似的方式开始流式传输下一个数据块。

有关扩展示例,请参阅 __main__.py 文件(命令行脚本),以及 libRaptorQ 文档以获取其C API信息,该模块对此进行了封装。

安装

这是一个针对Python 2.7的常规软件包(不是3.X)。

它使用并需要CFFI(可以通过pip安装)和libRaptorQ v0.1.x(作为libRaptorQ.so)安装到系统上。

libRaptorQ v1.x(与当前稳定版本0.1.9不同)具有不同的API,并且不会与此模块一起使用。

使用pip是最佳方式

% pip install libraptorq

如果您没有它,请使用

% easy_install pip
% pip install libraptorq

或者(另请参阅pip2014.compip安装指南

% curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python2
% pip install libraptorq

或者,如果您绝对必须

% easy_install libraptorq

但,您真的不应该这样做。

当前git版本可以这样安装

% pip install 'git+https://github.com/mk-fg/python-libraptorq.git#egg=libraptorq'

请注意,要在系统PATH和site-packages中安装东西,通常需要提升权限。请使用“install –user”,~/.pydistutils.cfgvirtualenv 以在自定义路径中进行无权限安装。

或者,可以直接在检出树中运行 ./rq 工具,无需任何安装,如果这是您唯一需要的东西。

随机笔记

  • 有关编码参数(如symbol_size和max_memory)指定不当时发生的情况以及为什么此模块的命令行界面没有为这些设置默认值的信息,请参阅 github-issue-1

  • libRaptorQ目前通过CFFI以“ABI模式”使用,以避免编译和编译器的额外麻烦,有关更多信息,请参阅CFFI关于此主题的文档

  • 在解码时,如果源块已经解码并且不需要额外符号,libRaptorQ可以对add_symbol()调用引发错误。

  • libRaptorQ允许指定“rq_type”参数以指定内部数据对齐大小(C++迭代器元素),该参数在模块中硬编码为RQ_ENC_32/RQ_DEC_32,以简化。

  • Python 3.X不兼容的原因是我根本就没有使用它(目前),所以不需要它,原则上没有反对它的理由。

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

libraptorq-18.3.0.tar.gz (12.2 kB 查看哈希值)

上传于 源代码

构建分发

libraptorq-18.3.0-py2-none-any.whl (17.7 kB 查看哈希值)

上传于 Python 2

由以下支持

AWSAWS云计算和安全赞助商DatadogDatadog监控FastlyFastlyCDNGoogleGoogle下载分析MicrosoftMicrosoftPSF赞助商PingdomPingdom监控SentrySentry错误记录StatusPageStatusPage状态页面