python-reedsolomon实际应用

2020/10/15更新:之前的代码错了:)

之前只对十进制列表算过编码,昨天试了下对字符串直接编码,然后发现结果很神奇。

我用一段伪随机生成的核酸序列举例吧(用random做的。搞生信,理解一下)

>>> from reedsolo import RSCodec
>>> rsc = RSCodec(6)
>>> ans = rsc.encode(b"CtttaAatUAGTTtUG")
>>> ans
bytearray(b'CtttaAatUAGTTtUG_$\xaf\xa5x>')

可以看到后面有奇怪的字符。这里解释一下,\x表示后面两位是十六进制。

同时,我也刚发现,原来对十进制进行编码时,也有问题,比如:

>>> from reedsolo import RSCodec
>>> rsd = RSCodec(6)
>>> rsd.encode([9,1,2,9]*4)
bytearray(b'\t\x01\x02\t\t\x01\x02\t\t\x01\x02\t\t\x01\x02\tQ\x7f_\xa3=\xef')

那么,当有9出现的时候,我下面的编码解码都是错的。也许还有别的数字也有这样的问题。

我当前的策略是按位解析。。。对单字符和双字符分别解析。

def _rsEncode(data, n):
    '''
    n 是实际编码长度,16 for example
    dat = bytearray(b'CtttaAatUAGTTtUG_$\xaf\xa5x>')

    :param data: bytearray
    :param n:
    :return:
    '''
    data = str(bytes(data))[2:-1]
    tail = data[n:]
    pos = tail.find("\\x")
    i = 0
    result = ''
    while i < len(tail):
        #print("start: " + str(i))
        if i == pos:
            # 取两位字符
            result += "." + tail[i+2:i+4]
            i += 4
            pos = tail.find("\\x", i)
        else:
            ...
            i += 1
    return result

需要注意的是,\和\t其实都是一个字符。


之前这篇 差错控制-reed-solomon编码 我鸽了,可能要 很久 才有空补了。当前业务上使用场景有限,现在只用一个 reedsolo 包足够了。

安装

直接pip 官方例子

编码

from reedsolo import RSCodec

def _rsEncode(data, n):
    '''
    Encode input data with Reed-Solomon codes. n bits for error correcting.
    :param data: input data, like "b'@\\x16\\x10\\xec\\x11\\xec\\x11\\xda(\\xf3\\xd4BG\\x96'"
    :param n: Length of result list.
    :return: A list of error correcting values. Decimal.
    '''
    res = []
    # remove b' and '
    temp = str(bytes(data))[2:-1]
    li = temp.split("\\x")
    # only retain encoded values
    for i in li[::-1]:
        size = len(i)
        if size == 1:
            res.append(ord(i))
        else:
            j = i[2:]
            # first 2 digits are hex
            temp_li = [int('0' + i[:2], 16)]
            while len(j) > 0: # single char
                temp_li.append(ord(j[0]))
                j = j[1:]
            # reverse
            res.extend(temp_li[::-1])
        if len(res) >= n:
            break
    return res[:n][::-1]

rsc = RSCodec(7)
# 我这个data_list是一个十进制整数列表
encode_ = rsc.encode(data_list)
# _rsEncode帮我把【纠错码】,也就是尾部附加的那些数字转为十进制
rs_tail = _rsEncode(encode_, 7)

解码

下面这个函数将十进制整数的list(业务数据附加纠错码)转为字符串。

def _rsDecode(data, n, m):
    '''
    Reed-Solomon Decoding.
    :param data: decimal list.
    :param n: length of ecc. (bytes)
    :param m: length of bussiness data. (bytes)
    :return: utf-8 string
    '''
    rsd = RSCodec(n)
    data = rsd.decode(data)[:m]
    hex_ = ""
    for i in data:
        hex_ += "{:02X}".format(i)
    # need to remove '@' at head
    hex_ = hex_[3:]
    while hex_[-1:] != "0":
        hex_ = hex_[:-2]
    hex_ = hex_[:-1]
    return bytearray.fromhex(hex_).decode("utf-8")

注意

  • RS的纠错能力是有限的,纠错码用几位要根据实际需求来。默认的是GF(2^8),也就是说,对于0~255的值是ok的。256以下就是8位表示嘛,所以如果超过8位,函数会自动切块,不保证速度。键盘上常用字符其实是够用的了。
>> rsc = RSCodec(12, nsize=4095)  # always use a power of 2 minus 1
>> rsc = RSCodec(12, c_exp=12)  # alternative way to set nsize=4095
  • 纠错能力:2*e + v <= n
    e:错误的位数
    v:缺失的位数(需要提供位置)
    n:纠错码长度
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Reed-Solomon是一种编码和解码算法,用于在传输和储存数据时进行错误检测和纠正。Python是一种通用的编程语言,它提供了许多工具和库来实现各种算法,包括Reed-Solomon。 在Python中,我们可以使用第三方库`pyfinite`来实现Reed-Solomon编码和解码。首先,您需要安装这个库。您可以使用pip命令进行安装: ``` pip install pyfinite ``` 安装完成后,您可以使用以下示例代码来进行Reed-Solomon编码和解码的实现: ```python from pyfinite import genericmatrix from pyfinite import genericgf from pyfinite import genericpoly # 定义有限域和生成多项式 field = genericgf.GenericGF(0x11d, 256) generator_poly = genericpoly.GenericPoly([1, 0], field) # 进行Reed-Solomon编码 encoder = genericmatrix.GenericMatrix(field, 1, 255) encoder.set(0, [your_data]) # 输入待编码的数据 encoder_gf = encoder.multiply(generator_poly) # 用生成多项式进行编码 # 进行Reed-Solomon解码 decoder = genericmatrix.GenericMatrix(field, 1, 255) decoder.set(0, encoder_gf) # 输入待解码的数据 decoder_gf = decoder.multiply(generator_poly.reciprocal()) # 用生成多项式的逆进行解码 decoded_data = decoder_gf[0] # 解码后的数据 # 输出结果 print("编码前的数据:", [your_data]) print("编码后的数据:", encoder_gf) print("解码后的数据:", decoded_data) ``` 上述代码示例了如何使用`pyfinite`库实现Reed-Solomon编码和解码。您可以根据您的实际需求调整代码中的参数和数据,以便进行自定义的Reed-Solomon操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值