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

时间:2015-01-25 13:23:06

标签: python encoding asn.1

我开始学习ASN.1并使用pyasn1进行实验。 默认情况下,pyasn1使用base 10来编码实数。 它也是支持基础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编码器的行为相同。

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

1 个答案:

答案 0 :(得分:0)

此行为对应于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