Функция кодирования Python не может быть декодирована - PullRequest
1 голос
/ 01 июля 2010

Я написал этот код Python, пытаясь преобразовать объекты в строку из нулей и единиц, но декодирование не удалось, потому что данные не могут быть выбраны.Это код:

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

Ответы [ 4 ]

2 голосов
/ 01 июля 2010

Я думаю, что есть несколько проблем, но одна из них заключается в том, что когда вы декодируете, вам нужно перебирать группы из 4 символов в вашей функции unbin (), а не отдельных символов, как вы делаете в настоящее время.

1 голос
/ 01 июля 2010

Я думаю, у меня есть лучшее решение для вас.Это должно быть еще более безопасно, поскольку оно «шифрует» все, а не только цифры:

MAGIC = 0x15 # CHOOSE ANY TWO HEX DIGITS YOU LIKE

# THANKS TO NAS BANOV FOR THE FOLLOWING:
unbin = tobin = lambda s: ''.join(chr(ord(c) ^ MAGIC) for c in s)
0 голосов
/ 02 июля 2010

Кстати ... base64.b16encode(base64.b16encode(data)) эквивалентно data.encode('hex').encode('hex'). И есть более простой и быстрый способ сделать отображение,

def tobin(numStr):
    return ''.join(("0000","0001","0010","0100","1000","1001","1010","1100","1101","1110")[int(c)] for c in numStr)

Сама идея этого кодирования, хотя и выглядит сложной на первый взгляд, не очень хороша. Во-первых, он не выполняет большую часть шифрования, поскольку каждая цифра из шестнадцатеричного дампа всегда сопоставляется одной и той же строке длиной 8 из 0 и 1 с:

>>> hexd = '0123456789ABCDEF'
>>> s = hexd.encode('hex')
>>> s
'30313233343536373839414243444546'
>>> s=''.join(["0000","0001","0010","0100","1000","1001","1010","1100","1101","1110"][int(c)] for c in s)
>>> s
'01000000010000010100001001000100010010000100100101001010010011000100110101001110100000011000001010000100100010001000100110001010'
>>> for i in range(0,len(s),8):
...     print hexd[i/8], s[i:i+8], chr(int(s[i:i+8],2))
... 
0 01000000 @
1 01000001 A
2 01000010 B
3 01000100 D
4 01001000 H
5 01001001 I
6 01001010 J
7 01001100 L
8 01001101 M
9 01001110 N
A 10000001 
B 10000010 ‚
C 10000100 „
D 10001000 ˆ
E 10001001 ‰
F 10001010 Š

Во-вторых, он увеличивает размер маринованного объекта 16 раз ! Даже если вы упакуете это путем преобразования каждых 8 битов '0' и '1' в байты (скажем, chr(int(encoded[i:i+8],2))), это все равно будет 2x маринадом.

0 голосов
/ 01 июля 2010

Ваши функции bin и unbin не являются инверсиями друг друга, потому что bin имеет предложение else, которое просто дословно помещает символы в вывод, но unbin не имеет предложения else для передачи их обратно.

...