这个python3代码的Python2版本用于编码

时间:2017-12-07 13:54:52

标签: python python-3.x python-2.7 encoding

我正在尝试使用python2版本2.7.13从this post(与python3版本3.5.3完美配合)中的答案运行代码:

def myencode_str(ori_str, key):
    enc = []
    for i in range(len(ori_str)):
        key_c = key[i % len(key)]
        enc_c = (ord(ori_str[i]) + ord(key_c)) % 256
        enc.append(enc_c)
    return (base64.urlsafe_b64encode(bytes(enc))).decode("utf-8") 

我正在使用以下解码fn:

def mydecode(enc_str, key):
    dec = []
    enc_str = base64.urlsafe_b64decode(enc_str)
    for i in range(len(enc_str)):
        key_c = key[i % len(key)]
        dec_c = chr((256 + enc_str[i] - ord(key_c)) % 256)
        dec.append(dec_c)
    return "".join(dec)

但是我收到以下错误消息:

    dec_c = chr((256 + enc_str[i] - ord(key_c)) % 256)
TypeError: unsupported operand type(s) for +: 'int' and 'str'

我尝试了以下更改的代码,但它们也不起作用:

    dec_c = chr((256 + int(enc_str[i]) - int(ord(key_c))) % 256)
ValueError: invalid literal for int() with base 10: '\xc3'

问题在哪里以及如何解决?

1 个答案:

答案 0 :(得分:1)

问题是bytes构造函数在收到整数列表时在Python2和Python3之间发生了变化:

  • 在Python3中,它构建一个字节字符串,其中每个字节从列表中接收代码
  • 在Python2中,它只是将列表转换为字符串(通过使用表示或字符串)

在Python3中,字节字符串是一个可迭代的字节(可以直接转换为整数),而它只是Python2中的一个字符串。

所以你的功能必须稍微改变一下:

def myencode_str(ori_str, key):
    enc = []
    for i in range(len(ori_str)):
        key_c = key[i % len(key)]
        enc_c = (ord(ori_str[i]) + ord(key_c)) % 256
        enc.append(enc_c)
    return (base64.urlsafe_b64encode(''.join([chr(i) for i in enc])))

def mydecode(enc_str, key):
    dec = []
    enc_str = [ord(i) for i in base64.urlsafe_b64decode(enc_str)]
    for i in range(len(enc_str)):
        key_c = key[i % len(key)]
        dec_c = chr((256 + enc_str[i] - ord(key_c)) % 256)
        dec.append(dec_c)
    return "".join(dec)

实际上,可以编写这些函数,以便在bytearray类的帮助下在Python2和Python3中使用相同的代码,这两个版本具有相同的行为。您只需选择输入是字节字符串还是unicode字符串。由于algorythm基于字节,我选择在以下代码中处理字节字符串。您需要对原始字符串和密钥进行编码(使用'utf8'以实现完全可移植性)并解码已解码的字符串以处理unicode字符串:

def myencode_str(ori_str, key):
    enc = []
    b = bytearray(ori_str)
    k = bytearray(key)
    for i, c in enumerate(b):
        key_c = k[i % len(key)]
        enc_c = (c + key_c) % 256
        enc.append(enc_c)
    return (base64.urlsafe_b64encode(bytes(bytearray(enc))))

def mydecode(enc_str, key):
    dec = []
    enc_str = bytearray(base64.urlsafe_b64decode(enc_str))
    k = bytearray(key)
    for i, c in enumerate(enc_str):
        key_c = k[i % len(key)]
        dec_c = (c - key_c) % 256
        dec.append(dec_c)
    return bytes(bytearray(dec))

然后你可以在Python2中做:

>>> myencode_str(b"abcdef", b"XYZ")
'ubu9vL7A'
>>> mydecode('ubu9vL7A', b"XYZ")
'abcdef'

并在Python3中:

>>> myencode_str(b"abcdef", b"XYZ")
b'ubu9vL7A'
>>> mydecode(b'ubu9vL7A', b"XYZ")
b'abcdef'