Python ASN.1使用pyasn1在基2中进行实数编码

Python ASN.1使用pyasn1在基2中进行实数编码,python,encoding,asn.1,Python,Encoding,Asn.1,我开始学习ASN.1,并使用pyasn1进行实验。 默认情况下,pyasn1使用基数10编码实数。 它也支持base 2,我需要在我的程序中使用base 2。 但是它看起来编码有问题。 我发现在基数2中对数字0.5和1.0进行编码时出现了奇怪的行为。 测试代码为: from pyasn1.type import univ from pyasn1.codec.ber import encoder, decoder import binascii for i in xrange(4): r

我开始学习ASN.1,并使用pyasn1进行实验。 默认情况下,pyasn1使用基数10编码实数。 它也支持base 2,我需要在我的程序中使用base 2。 但是它看起来编码有问题。 我发现在基数2中对数字0.5和1.0进行编码时出现了奇怪的行为。 测试代码为:

from pyasn1.type import univ
from pyasn1.codec.ber import encoder, decoder
import binascii

for i in xrange(4):
    r=univ.Real((1,2,-i))
    m=encoder.encode(r)
    print r,"->",decoder.decode(m)[0],"data:",binascii.b2a_hex(m)
输出为:

1.0 -> 2.0 data: 0903830101
0.5 -> 2.0 data: 0903830101
0.25 -> 0.25 data: 090380fe01
0.125 -> 0.125 data: 090380fd01
数字0.5和1.0编码为同一序列,解码为2.0。 在BER和DER编码器中都有相同的行为


您能帮我找出问题所在吗?

此行为与pyasn1开发版本中已修复的错误相对应。 对于当前版本,修复程序将进行下一次更改: 在文件pyasn1/codec/ber/encoder.py中查找行编码指数

        eo = null
        while e not in (0, -1):
            eo = int2oct(e&0xff) + eo
            e >>= 8
        if e == 0 and eo and oct2int(eo[0]) & 0x80:
            eo = int2oct(0) + eo
        n = len(eo)
        if n > 0xff:
            raise error.PyAsn1Error('Real exponent overflow')
        if n == 1:
            pass
        elif n == 2:
            fo |= 1
        elif n == 3:
            fo |= 2
        else:
            fo |= 3
            eo = int2oct(n//0xff+1) + eo
并用这些线替换它们

        eo = null
        while True:
            _e = e&0xff
            eo = int2oct(_e) + eo
            e >>= 8
            if e==0: # positive number ends up with 0
                if not _e&0x80: # sequence should start with positive byte
                    break
            elif e==-1: # negative number ends up with -1
                if _e&0x80: # sequence should start with negative byte
                    break
        n = len(eo)-1
        if n > 0xff:
            raise error.PyAsn1Error('Real exponent overflow')
        if n < 3:
            fo |= n
        else:
            fo |= 3
            eo = int2oct(n) + eo

看起来这个bug在Pyasn1的最新版本中得到了修复。实际上,这个修复目前只在开发版本中。