Python编码函数无法解码
我编写了这段 python 代码,试图将对象转换为一串 1 和 0,但解码失败,因为无法对数据进行 unpickle。这是代码:
def encode(obj):
'convert an object to ones and zeros'
def tobin(str):
rstr = ''
for f in str:
if f == "0": rstr += "0000"
elif f == "1": rstr += "0001"
elif f == "2": rstr += "0010"
elif f == "3": rstr += "0100"
elif f == "4": rstr += "1000"
elif f == "5": rstr += "1001"
elif f == "6": rstr += "1010"
elif f == "7": rstr += "1100"
elif f == "8": rstr += "1101"
elif f == "9": rstr += "1110"
else: rstr += f
return rstr
import pickle, StringIO
f = StringIO.StringIO()
pickle.dump(obj, f)
data = f.getvalue()
import base64
return tobin(base64.b16encode(base64.b16encode(data)))
def decode(data):
def unbin(data):
rstr = ''
for f in data:
if f == "0000": rstr += "0"
elif f == "0001": rstr += "1"
elif f == "0010": rstr += "2"
elif f == "0100": rstr += "3"
elif f == "1000": rstr += "4"
elif f == "1001": rstr += "5"
elif f == "1010": rstr += "6"
elif f == "1100": rstr += "7"
elif f == "1101": rstr += "8"
elif f == "1110": rstr += "9"
return rstr
import base64
ndata = base64.b16decode(base64.b16decode(unbin(data)))
import pickle, StringIO
f = StringIO.StringIO(ndata)
obj = pickle.load(f)
return obj
I wrote this python code in an attempt to convert objects to a string of ones and zeros, but the decoding fails because the data can't be unpickled. This is the code:
def encode(obj):
'convert an object to ones and zeros'
def tobin(str):
rstr = ''
for f in str:
if f == "0": rstr += "0000"
elif f == "1": rstr += "0001"
elif f == "2": rstr += "0010"
elif f == "3": rstr += "0100"
elif f == "4": rstr += "1000"
elif f == "5": rstr += "1001"
elif f == "6": rstr += "1010"
elif f == "7": rstr += "1100"
elif f == "8": rstr += "1101"
elif f == "9": rstr += "1110"
else: rstr += f
return rstr
import pickle, StringIO
f = StringIO.StringIO()
pickle.dump(obj, f)
data = f.getvalue()
import base64
return tobin(base64.b16encode(base64.b16encode(data)))
def decode(data):
def unbin(data):
rstr = ''
for f in data:
if f == "0000": rstr += "0"
elif f == "0001": rstr += "1"
elif f == "0010": rstr += "2"
elif f == "0100": rstr += "3"
elif f == "1000": rstr += "4"
elif f == "1001": rstr += "5"
elif f == "1010": rstr += "6"
elif f == "1100": rstr += "7"
elif f == "1101": rstr += "8"
elif f == "1110": rstr += "9"
return rstr
import base64
ndata = base64.b16decode(base64.b16decode(unbin(data)))
import pickle, StringIO
f = StringIO.StringIO(ndata)
obj = pickle.load(f)
return obj
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为存在几个问题,但其中一个是当您解码时,您需要在 unbin() 函数中迭代 4 个字符组,而不是像您当前所做的那样迭代单个字符。
I think there are several problems, but one is that when you decode, you need to iterate through groups of 4 characters in you unbin() function, not single characters like you are currently doing.
我想我有更好的解决方案给你。这应该更安全,因为它“加密”所有内容,而不仅仅是数字:
I think I have a better solution for you. This should be even more secure, since it "encrypts" everything, not just numbers:
您的
bin
和unbin
函数不是彼此相反的,因为bin
有一个 else 子句,它只是将字符逐字放入输出中,但unbin
没有 else 子句将它们传回。Your
bin
andunbin
functions aren't inverses of each other, becausebin
has an else clause that just puts the characters verbatim into the output, butunbin
has no else clause to pass them back.顺便说一下...
base64.b16encode(base64.b16encode(data))
相当于data.encode('hex').encode('hex')
。并且有更简单、更快的方法来进行映射,这种编码的整个思想虽然表面上看起来很复杂,但并不是很好。首先,它没有进行太多加密,因为十六进制转储中的每个数字始终与相同的 8 长度字符串 0 和 1 匹配:
其次,它会将 pickle 对象的大小放大 16 倍!即使您通过将“0”和“1”的每 8 位转换为字节来打包(例如
chr(int(encoded[i:i+8],2))
),这仍然是2x 泡菜。By the way...
base64.b16encode(base64.b16encode(data))
is equivalent todata.encode('hex').encode('hex')
. And there is simpler and faster way to do the mapping,The whole idea of this encoding, while seeming complicated on the surface, is not very good. First, it does not do much of encryption, since each digit from the hex dump gets matched always to the same 8-length string of 0 and 1s:
Secondly, it blows up the size of the pickled object 16 times! Even if you pack this by converting every 8 bits of '0' and '1' to bytes (say
chr(int(encoded[i:i+8],2))
), that still is 2x the pickle.