此python3代码的Python2版本用于编码

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

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

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'

问题出在哪里,如何解决?

最佳答案

问题在于,当接收整数列表时,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 字符串。由于该算法基于字节,因此我选择在以下代码中处理字节字符串。您需要对原始字符串和 key 进行编码(使用“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'

关于此python3代码的Python2版本用于编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47696664/

相关文章:

python - 在turtle.bye()之后重新打开turtle

python - 为什么在 Linux 上导入 numpy 会增加 1 GB 的虚拟内存?

python-2.7 - RASA 没有识别出正确的 Intent

python - 如何正确制作我自己的模块以在其中导入另一个模块?

python - 将矩阵展平为包含值索引位置的数组

python - 未命名的 Python 对象具有相同的 id

python - 服务器基础设施、文件上传项目

java - 在java中使用for循环打印星号

python - 打印来自 2 个不同列表的数据及其索引

python - 使用 Python 3.4 从 Google Patents 下载文件