在python 3.6中处理自定义编码时遇到类型错误

在python 3.6中处理自定义编码时遇到类型错误,python,python-3.x,base64,Python,Python 3.x,Base64,我编写了一个自定义编码代码片段。当我在pyton 3.6上运行它时,我得到了类型错误。我想不出确切的答案。代码片段在Python2.7中运行良好 import os import sys import base64 def encode(key, clear): """encode custom """ enc = [] for i in range(len(clear)): key_c = key[i % len(key)] enc_c

我编写了一个自定义编码代码片段。当我在pyton 3.6上运行它时,我得到了类型错误。我想不出确切的答案。代码片段在Python2.7中运行良好

import os
import sys
import base64

def encode(key, clear):
    """encode custom """
    enc = []
    for i in range(len(clear)):
        key_c = key[i % len(key)]
        enc_c = chr((ord(clear[i]) + ord(key_c)) % 256)
        #change the int or str
        enc.append(enc_c)
    return base64.urlsafe_b64encode("".join(enc))

clear = "ABCDEFGH"
encode_var = encode("crumbs", clear)
错误日志:

(py3) C:\Dev\crumbles>python s1.py
Traceback (most recent call last):
  File "s1.py", line 45, in <module>
    encode_var = encode("crumbs", clear)
  File "s1.py", line 42, in encode
    return base64.urlsafe_b64encode("".join(enc))
  File "C:\Users\Cookie1\Anaconda3\envs\py3\lib\base64.py", line 118, in urlsafe
_b64encode
    return b64encode(s).translate(_urlsafe_encode_translation)
  File "C:\Users\Cookie1\Anaconda3\envs\py3\lib\base64.py", line 58, in b64encod
e
    encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'
(py3)C:\Dev\crumbles>pythons1.py
回溯(最近一次呼叫最后一次):
文件“s1.py”,第45行,在
encode_var=encode(“碎屑”,清除)
文件“s1.py”,第42行,编码
返回base64.urlsafe_b64encode(“.join(enc))
文件“C:\Users\Cookie1\Anaconda3\envs\py3\lib\base64.py”,第118行,在urlsafe中
_B64编码
返回b64encode.translate(\u urlsafe\u encode\u translate)
文件“C:\Users\Cookie1\Anaconda3\envs\py3\lib\base64.py”,第58行,在b64encod中
E
encoded=binascii.b2a_base64(s,换行符=False)
TypeError:需要类似字节的对象,而不是“str”
您传递的是文本,而不是二进制
字节
对象。
base64.urlsafe\u b64encode()
函数需要字节,而不是文本

改为生成字节:

from itertools import cycle

def encode(key, clear):
    """encode custom """
    key, clear = cycle(key.encode()), clear.encode() 
    enc = bytes((c + k) % 256 for c, k in zip(clear, key))
    return base64.urlsafe_b64encode(enc)
我使用了一些迭代器技巧来生成
bytes()
接受的整数

请注意,在创建单密钥加密时,使用XOR生成加密字节更为常见:

from operator import xor

key, clear = cycle(key.encode()), clear.encode() 
enc = bytes(map(xor, clear, key))

这是因为XOR可以通过使用相同的键进行简单的反转;clear XOR key生成加密文本,加密XOR key再次生成明文。

我们可以加入字节吗?是的,有一个
bytes.join()
方法,但它也只能加入其他
bytes
对象。您好@MartijnPieters。你的回答对我有帮助。但是我不能理解你贴的代码。请你简单解释一下。
字节
实际上是一个整数序列,其值介于0和255之间;当你打印这些文件时,你可能会看到ASCII字符,但在它们的核心仍然是一堆数字。在Python 2中,您需要使用
ord()
从一个字符到一个整数,然后使用
chr()
从一个整数到另一个字符,但在迭代字节(给您数字)和构建新的字节对象(它接受数字)时,不需要所有这些。
zip()
允许您将两个序列配对。它会同时给出输入的第一个值,然后是第二个值,以此类推,直到完成其中一个输入
cycle()
允许您无限期地重复序列的值。因此,
zip()
将输入的明文字节与键字节放在一起,键字节根据需要在所有字符中反复循环,并为您提供带有正确键字节的单个明文字节。接下来要做的就是从这两个字节中生成一个新的加密字节。