使用IDEA算法加密MP3文件[UnicodeDecodeError:'utf8'编解码器无法解码位置6中的字节0xf4:无效的连续字节]

2024-06-10 19:25:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经调查了stackoverflow上的类似错误,但没有任何帮助 我已经实现了IDEA算法,该算法采用编码的十六进制数据输入(16十六进制,相当于IDEA纯文本大小的64位) 例如,utf-8编码/解码:

KEY = int('006400c8012c019001f4025802bc0320', 16)
plain_text = 'HiStackO'
cryptor = IDEA(KEY)  # Initialize cryptor with 128bit key
cipher_text = cryptor.encrypt(plain_text)
deciphered_text = cryptor.decrypt(cipher_text)

下面是加密/解密函数 输出:

Original text = HiStackO
Hex encoded text = 4869537461636b4f
Ciphered text = b6315c103ab29de1
Deciphered text = HiStackO

我面临一些文本字符串的问题,例如'thinghwr'成功解密/加密,但是'thingher'我得到了

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcd in position 1: invalid continuation byte

我试过latin-1和其他编码器,但结果不是原来的..
至于字节,我试图通过一次读取8个字节来加密MP3歌曲文件,对新加密的文件进行解码、加密和写入加密

cryptor = IDEA(KEY)  # Initialize cryptor with 128bit key

in_file = open("song.mp3", "rb")
out_file = open("encrypted.mp3", "w")

bytes8 = in_file.read(8)

while bytes8:
    res = cryptor.encrypt(bytes8.decode("latin-1"), codec="latin-1")
    print(res)
    res = ''.join('0' * (16 - len(res))) + res
    out_file.write(res)
    bytes8 = in_file.read(8)

in_file.close()
out_file.close()

每个“res”是16个十六进制数,其中包含加密/解密文本并写入文件。
文件已成功加密,没有任何问题

至于解密,我使用以下方法:

in_file = open("encrypted.mp3", "r")
out_file = open("decrypted.mp3", "wb")

bytes8 = in_file.read(16)
while bytes8:
    res = cryptor.decrypt(bytes8)
    print(res)
    out_file.write(res.encode())
    bytes8 = in_file.read(16)

in_file.close()
out_file.close()

在解密过程中,在成功解密几次之后,会出现以下错误:

line 136, in decrypt
    return bytes.fromhex(res).decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 0: invalid start byte

第136行是解密函数:

        res = self.calculate_cipher(self.dec_sub_keys, cipher_text)
        res = ''.join('0' * (16 - len(res))) + res
        return bytes.fromhex(res).decode()

我尝试过不同的编码,但没有效果 我做错了什么?我是Python新手,以前处理过编解码器。
加密/解密函数:

def encrypt(self, plain_text='', is_hex=False, codec='utf-8'):
    if not is_hex:
        plain_text = plain_text.encode(codec).hex()
    plain_text = get_bin_block(plain_text)
    return self.calculate_cipher(self.enc_sub_keys, plain_text)

def decrypt(self, cipher_text='', codec='utf-8'):
    cipher_text = get_bin_block(cipher_text)
    res = self.calculate_cipher(self.dec_sub_keys, cipher_text)
    res = ''.join('0' * (16 - len(res))) + res
    return bytes.fromhex(res).decode(codec)

get_bin_block list是一个函数,它将文本转换为4个16位二进制块,用于计算加密/解密


Tags: textin文本selfresoututfcodec
1条回答
网友
1楼 · 发布于 2024-06-10 19:25:00
    res = self.calculate_cipher(self.dec_sub_keys, cipher_text)
    res = ''.join('0' * (16 - len(res))) + res
    return bytes.fromhex(res).decode()

calculate_cipher时,根据cipher_text的不同,可能会得到任意十六进制数字序列

然后,当您尝试.decode()对应的bytes时,默认情况下Python会尝试UTF-8编码。这种编码不能将每个可能的字节序列解释为文本;某些值和序列是非法的。你说你“尝试了不同的编码”;但是您必须选择一个真正适用于此目的的,并且确保在整个程序中一致使用它

问题不在于您正在读取二进制文件。问题是,您试图将加密数据存储为二进制,尽管这是一个非常复杂的系统,需要计算十六进制数字(作为文本),找到与这些数字对应的字节,将这些字节解码回字符串以从模块返回,然后再次编码以写入文件。如果你想生成字节,你应该直接生成字节。或者,没有任何东西表明您不能编写一个文本文件来表示二进制文件的加密结果,反之亦然,只要您能够证明该过程是可逆的

在这里有一个适当的understanding of the fundamentals是非常重要的。你不能期望跳过步骤,只是为当前的问题找到一个解决方案,继续你的生活——你会在下一次机会中再次绊倒

相关问题 更多 >