我在试着解码和编码一个二维码。QR码是base45编码的,之后是asn1编码的。解码工作正常。在这之后,我想再编码一次。base45解码后的结果与ASN1编码后的结果略有不同。
代码如下:
#! /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方法做什么更改才能得到完全相同的输出?
发布于 2021-10-10 08:39:20
简短的回答是...
除非您知道要编码的数据的规范,否则不能使用python asn1.Encoder。你要做的第一件事是查看你的二维码携带的数据的ASN.1规范。
长长的答案..。
为了理解我的意思,你可以看看https://pypi.org/project/asn1tools/,它会告诉你当你想要使用asn1/python的时候是什么过程。
尝试以下测试...
在您的代码中,将
b45_decoded = base45decode_nl(data)
print('before decoding / encoding')
print(b45_decoded)使用
b45_decoded = base45decode_nl(data)
print('before decoding / encoding')
print(b45_decoded.hex())结果将是一个仅包含十六进制字符(0到F)的字符串
before decoding / encoding
3082026a020100022012e8a6e4693ced7bfa111227f75134aca71914358d00c34b17ebe49eb ....复制整个数据并将其粘贴到https://asn1.io/asn1playground/的解码选项卡中
输出将是
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部分组成的结构。这并没有告诉你它是什么意思(同样,你需要它的规范)。
另请注意,这是一种标记/长度/值编码
还有一件事..。
运行脚本时,您会看到
decoded asn1_obj
[0, 8552691641371642315207690017304824071043033037718558536544370073022402689101, 49268998317399832353736153768064371574626738522454049754099967437769709104310153609419233826877129804699795832362376712815509777453876457088841057013114352195643598128717108189839059529627445516705110559750713315964799043200407446690141492417247324685581653291574436663012628249066333485906592079172004705549, 49545515259154895522776867107959247032241047651980572443481917331143789403307139106555023968391340296360761238102083435099286993359857518, 7463954613777398261540270129601931803174222687130155761347994847425322491183229539732191198415826129672984792140024846081031144727556269931620272207040926338693607156199863455849443514025962426861121889546981280059686356901102682907001113258526002924172374302439709804314739830145508425336941142618773720272632415685260123356955161489134413604652892038340458427564488213207319660351733296444266493507445217438295664429771376840180237292580120261971321393055748802007069008017175471042800839302970504855484030669136380196262086189703554019361768087619371773861096653352702590133156777381984232268805659708171263123, 8995728107811269294519662596375119434427697506197921896277098071616873267360774813635548449786430125954107935654004828703451862806879219403683135630175078760507502448619423267753, [498988475518323990323119632714979941, 99, 99, 464791400517651978018913, 25707, 133, 133, 26211, 111]]数据不容易读取,因为这是一个以整数表示的原始数据数组。但你可以清楚地认出这些小数字
前0是上述结构的第一部分,最后的99是上述( 63)子结构的第2部分和第3部分
您注意到这些标记不在asn1decode()返回的数组中
因此,有很多原因导致您的脚本不能执行您希望它执行的操作:)
https://stackoverflow.com/questions/69472190
复制相似问题