我开始学习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编码器的行为相同。
你能帮我找出问题所在吗?
答案 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