首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >asn1解码与编码的差异

asn1解码与编码的差异
EN

Stack Overflow用户
提问于 2021-10-06 20:15:19
回答 1查看 179关注 0票数 0

我在试着解码和编码一个二维码。QR码是base45编码的,之后是asn1编码的。解码工作正常。在这之后,我想再编码一次。base45解码后的结果与ASN1编码后的结果略有不同。

代码如下:

代码语言:javascript
复制
#! /usr/bin/env python3
from typing import List, Dict, Optional
from PIL import Image
from pyzbar import pyzbar

import asn1
import json
import qrcode

def base45decode_nl(s: str) -> bytes:
    base45_nl_charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"

    s_len = len(s)
    res = 0
    for i, c in enumerate(s):
        f = base45_nl_charset.index(c)
        w = 45 ** (s_len - i - 1)
        res += f * w
    return res.to_bytes((res.bit_length() + 7) // 8, byteorder='big')

def base45encode_nl(buf: bytes) -> str:
    base45_nl_charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"
    res = ""
    divident = int.from_bytes(buf, 'big')
    
    while(divident > 0): 
      divident, remainder = divmod(divident, 45)
      res += base45_nl_charset[remainder]

    return reversed_string(res)

def reversed_string(a_string):
    return a_string[::-1]

def asn1decode(d: asn1.Decoder) -> List:
    res = []
    while not d.eof():
        tag = d.peek()
        if tag.typ == asn1.Types.Primitive:            
            tag, value = d.read()
            res.append(value)
        elif tag.typ == asn1.Types.Constructed:            
            d.enter()
            res.append(asn1decode(d))
            d.leave()
    return res

def asn1encode(d: asn1.Encoder,l: List) -> asn1.Encoder:
    d.enter(asn1.Types.Constructed)
    for i, x in enumerate(l):
        if isinstance(x, list):            
            d = asn1encode(d, x)
        else:
            d.write(x)
    d.leave()
    return d

import json
import sys
import zlib
import base45
import cbor2
from cose.messages import CoseMessage 

data = 'B4V.W9D:LWJ5W2S6A$XQ9N* Y252O4%%  ZNK**$840VPY8T7$J0GR$8L2%VMO/20/3C.C.L XO:FN%IWW.TI+G3KW2RA+ $6T1 BQAGU6HJ35D.2YPIT*6Y3C733IOBZIKEWP4L/$9TX6QUVQFFZWJ+RY/JV6N3%NX%Y4XX43J182O/.AELM1%E-D*Q+8*O1CG*9/5ENUJ0HXT*PJXJ*XE-6QFMM7*B$IFEY04:-PN14PX3% Q5-JQF9$YJFVBSUD*P/AXHJRNUIA:SCX*SBIQ*BHZG$PJ+LG-S*:0.GZ8M4HO.XLM$BKZG7H/BVRUW$7WH$B3$L-T58KK$20EDRZW1B*VJ1Q5VC:X/.5*OQJ/EA92-8J*-QL6J+3NX:C5%%XZ4LLIS31KKPA9:1FP++KT:.QFRZ%M5R$I2*DM36M%BW/3.LS9MX6YE8KU4S-.Q%W2ZCI7CQ79E/X342+5T3ODK8X.-F02J-GMF18KCE.5NDV2V8I/5L0GVNPQRF+T3A*$%HI3-$R3+*RO/X8N.RG7LBFJP5SO9QAD:KYRP978DTHFL39368JXWSO2CKLQTYDZ45CF0FE9J3$$6+ZX RSNRQ6+HV%DE$V:O/Q8FYO+.NZFL6R8R8UE.0:A*Q9$8HYB+WZ26UM%.4R4 25AA7XQW.NYAJCO6+-C QZEPKLYS6G0Z/YGHPR*+YKEDO*3LE:KP HT3NCJPRNRG9K0Y84*C-7N2-BQJXY/+D-VF IIQTJ6-AV83%1Y8JMXN1I6/JSHS+HEG+VU+8UX:LL*Y%B*$G$D4H9HZVMHKWT2-87UTR+EZIWJ*IOTQ70.V%CLHVY  2-HFW4BA6-+FWIW6C:WDS /FU2I9G$LXL$B/MY*WQYMN*R00IQZJJ- 6QFX*$%-9ZGS3%G'

b45_decoded = base45decode_nl(data)
print('before decoding / encoding')
print(b45_decoded)

asn1_decoder = asn1.Decoder()
asn1_decoder.start(b45_decoded)
asn1_obj = asn1decode(asn1_decoder)[0]
print('decoded asn1_obj')
print(asn1_obj)

asn1_encoder = asn1.Encoder()
asn1_encoder.start()
asn1_encoder = asn1encode(asn1_encoder, [asn1_obj])
asn1_encoded_output = asn1_encoder.output()

print('after decoding / encoding')
print(asn1_encoded_output)

输出的开头如下所示:

b'0\x82\x02j\x02

b'?\x82\x02p?\x82\x02k\x02\

我怀疑asn1encode方法是错误的。我应该对asn1encode方法做什么更改才能得到完全相同的输出?

EN

回答 1

Stack Overflow用户

发布于 2021-10-10 08:39:20

简短的回答是...

除非您知道要编码的数据的规范,否则不能使用python asn1.Encoder。你要做的第一件事是查看你的二维码携带的数据的ASN.1规范。

长长的答案..。

为了理解我的意思,你可以看看https://pypi.org/project/asn1tools/,它会告诉你当你想要使用asn1/python的时候是什么过程。

尝试以下测试...

在您的代码中,将

代码语言:javascript
复制
b45_decoded = base45decode_nl(data)
print('before decoding / encoding')
print(b45_decoded)

使用

代码语言:javascript
复制
b45_decoded = base45decode_nl(data)
print('before decoding / encoding')
print(b45_decoded.hex())

结果将是一个仅包含十六进制字符(0到F)的字符串

代码语言:javascript
复制
before decoding / encoding
3082026a020100022012e8a6e4693ced7bfa111227f75134aca71914358d00c34b17ebe49eb ....

复制整个数据并将其粘贴到https://asn1.io/asn1playground/的解码选项卡中

输出将是

代码语言:javascript
复制
OSS Nokalva TLV Print Utility  Version 8.6.1
Copyright (C) 1997-2021 OSS Nokalva, Inc.  All rights reserved.


30 82026A(618)
  02 01 00
  02 20 12E8A6E4693CED7BFA111227F75134ACA71914358D00C34B17EBE49EB2C4784D
  02 8180(128) 4629505D6ED76C40573A65B4F3681C4B921C545B9A37819DC1A80B08097291...
  02 39 442A6F5B7CC5456E9CD4685041C81199624C6920207EF947BC995204AAAA9F61E719...
  02 81FF(255) 0F22E0284AE0CF97EE79144A2F4B52E057D1D0DAAD86C7DEA69444A3311B73...
  02 4B 008E134CAC21D0C66F56FF440764BA8F84D06B4C323F531AB02406AF29DF037807B7...
  30 36
    02 0F 601A0802042610ACAEA65A86865A65
    02 01 63
    02 01 63
    02 0A 626C646E686C6C686061
    02 02 646B
    02 02 0085
    02 02 0085
    02 02 6663
    02 01 6F

您只知道数据是有效的,并且是一个由7个部分组成的结构。第7部分是由9部分组成的结构。这并没有告诉你它是什么意思(同样,你需要它的规范)。

另请注意,这是一种标记/长度/值编码

还有一件事..。

运行脚本时,您会看到

代码语言:javascript
复制
decoded asn1_obj
[0, 8552691641371642315207690017304824071043033037718558536544370073022402689101, 49268998317399832353736153768064371574626738522454049754099967437769709104310153609419233826877129804699795832362376712815509777453876457088841057013114352195643598128717108189839059529627445516705110559750713315964799043200407446690141492417247324685581653291574436663012628249066333485906592079172004705549, 49545515259154895522776867107959247032241047651980572443481917331143789403307139106555023968391340296360761238102083435099286993359857518, 7463954613777398261540270129601931803174222687130155761347994847425322491183229539732191198415826129672984792140024846081031144727556269931620272207040926338693607156199863455849443514025962426861121889546981280059686356901102682907001113258526002924172374302439709804314739830145508425336941142618773720272632415685260123356955161489134413604652892038340458427564488213207319660351733296444266493507445217438295664429771376840180237292580120261971321393055748802007069008017175471042800839302970504855484030669136380196262086189703554019361768087619371773861096653352702590133156777381984232268805659708171263123, 8995728107811269294519662596375119434427697506197921896277098071616873267360774813635548449786430125954107935654004828703451862806879219403683135630175078760507502448619423267753, [498988475518323990323119632714979941, 99, 99, 464791400517651978018913, 25707, 133, 133, 26211, 111]]

数据不容易读取,因为这是一个以整数表示的原始数据数组。但你可以清楚地认出这些小数字

前0是上述结构的第一部分,最后的99是上述( 63)子结构的第2部分和第3部分

您注意到这些标记不在asn1decode()返回的数组中

因此,有很多原因导致您的脚本不能执行您希望它执行的操作:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69472190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档