Skip to main content
 首页 » 编程设计

python之zlib TypeError : a bytes-like object is required, 不是 'str'

2025年05月04日31落叶无声

我使用此代码对文本进行编码和压缩。但它不能正常工作:

Traceback (most recent call last): File "E:\SOUND.py", line 114, in <module> 
unhexsring = str(zlib.decompress(unhexsring).encode('utf8')) 
TypeError: a bytes-like object is required, not 'str'  

你能帮帮我吗?

import zlib,gzip 
 
def str2hex(s): 
    return binascii.hexlify(bytes(str.encode(s))) 
 
 
def hex2str(h): 
    return binascii.unhexlify(h) 
 
hexstring = input() 
if len(hexstring) > 200: 
    hexstring = str(zlib.compress(hexstring.encode('utf-8'))) 
    print(hexstring) 
hexstring = str2hex(hexstring) 
ph = str(hexstring.decode('utf-8')) 
print(ph) 
 
#decompressing text 
unhexsring = hex2str(hexstring).decode('utf8') 
if 'x' in str(unhexsring): 
    print('compressed') 
    unhexsring = str(zlib.decompress(unhexsring).encode('utf8')) 
print(unhexsring) 

此代码不会解压缩 zlib 压缩的文本。

所以编码效果很好。

我的问题是,当我获取编码字符串并压缩它时,我无法解压缩它。 它应该如何工作:

1>s = input('some text') 
2>if len(s) > 200: s = str(zlib.compress(s.encode('utf-8')))  
3>encoding it with str2hex() 
4>decode it with hex2str() 
5>str(zlib.decompress(unhexs).encode('utf8'))  <---------- HERE 

而且我无法正确解压它,因为得到这个:

下一步控制台转储

Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32 
Type "copyright", "credits" or "license()" for more information. 
>>>  
========================= RESTART: E:\SOUND.py ========================= 
dghlkdushfgkjdsfhglkjhsdfgjhdskfjhgkdsfhgkjdhfgkjsdhfgjkhsdkjfghlkjsdhgkjhsdfjghdksjhgkjsdhgkjhsdfkjghdskfjghkdjghdghlkdushfgkjdsfhglkjhsdfgjhdskfjhgkdsfhgkjdhfgkjsdhfgjkhsdkjfghlkjsdhgkjhsdfjghdksjhgkjsdhgkjhsdfkjghdskfjghkdjghdghlkdushfgkjdsfhglkjhsdfgjhdskfjhgkdsfhgkjdhfgkjsdhfgjkhsdkjfghlkjsdhgkjhsdfjghdksjhgkjsdhgkjhsdfkjghdskfjghkdjghdghlkdushfgkjdsfhglkjhsdfgjhdskfjhgkdsfhgkjdhfgkjsdhfgjkhsdkjfghlkjsdhgkjhsdfjghdksjhgkjsdhgkjhsdfkjghdskfjghkdjgh 
b'x\x9c\xed\x8d\xb1\r\xc0@\x08\x03\x97\xb5\xb0e\x7f\x87\xb2\x7f\x9eO\x93\x05\xd2\xa5\x02\x1d>\x0cj\x05W\xab\x18\xa3K\\\xb1\x1aE\x0b\x9d\xb2\x98\x83\xf7\xf5dz\x86\xb3#q\x8d<\x84\x8fc\n\xe9Q^0C\xe7\x13\x15\xcc\xfe7~\xd0x\x03\x88\x05\xbb\x9d' 
6227785c7839635c7865645c7838645c7862315c725c786330405c7830385c7830335c7839375c7862355c786230655c7837665c7838375c7862325c7837665c7839654f5c7839335c7830355c7864325c7861355c7830325c7831643e5c7830636a5c783035575c7861625c7831385c7861334b5c5c5c7862315c783161455c7830625c7839645c7862325c7839385c7838335c7866375c786635647a5c7838365c78623323715c7838643c5c7838345c783866635c6e5c786539515e30435c7865375c7831335c7831355c7863635c786665377e5c786430785c7830335c7838385c7830355c7862625c78396427 
compressed 
Traceback (most recent call last): 
  File "E:\SOUND.py", line 114, in <module> 
    unhexsring = str(zlib.decompress(unhexsring).encode('utf8')) 
TypeError: a bytes-like object is required, not 'str' 

请您参考如下方法:

你在这里看到的异常:

unhexsring = str(zlib.decompress(unhexsring).encode('utf8')) 
    TypeError: a bytes-like object is required, not 'str' 

被引发是因为 zlib.decompress 需要 bytes。这很容易通过改变来解决

unhexsring = hex2str(hexstring).decode('utf8')    # -> str 

到

unhexsring = hex2str(hexstring)    # -> bytes 

但是这会导致一个新的错误:

unhexsring = zlib.decompress(unhexsring) 
    zlib.error: Error -3 while decompressing data: incorrect header check 

这是因为这条线而发生的:

hexstring = str(zlib.compress(hexstring.encode('utf-8'))) 

在 bytes 实例上调用 str 不会将 bytes 转换为 str,它会转换字节' repr 到 str。

>>> bs = 'Hello World'.encode('utf-8') 
>>> print(repr(bs)) 
b'Hello World' 
>>> s = str(bs) 
>>> print(repr(s)) 
"b'Hello World'"    # <- note the b.... 

str 转换是在压缩数据的前面插入一个“b”,因此破坏了 header 。让我们暂时将 hexstring 保留为 bytes 对象

hexstring = zlib.compress(hexstring.encode('utf-8')) 

但现在代码引发了另一个异常:

return binascii.hexlify(bytes(str.encode(s))) 
    TypeError: descriptor 'encode' requires a 'str' object but received a 'bytes' 

s 现在是一个 bytes 对象,所以没有必要尝试转换它(注意 str.encode 返回 bytes 无论如何,所以 bytes 调用将是多余的,即使 s 是一个字符串)。

所以str2hex变成了

def str2hex(s): 
    return binascii.hexlify(s) 

现在又出现了另一个错误:

unhexsring = str(zlib.decompress(unhexsring).encode('utf8')) 
    AttributeError: 'bytes' object has no attribute 'encode' 

zlib.decompress 的输出是一个bytes 对象,因此它已经被编码(假设它是一个字符串开头)。你想解码它以获得 str:

unhexsring = zlib.decompress(unhexsring).decode('utf8') 

这是您的代码版本,可以作为脚本从命令提示符运行:

import binascii 
import random 
import string 
import zlib 
 
def str2hex(s): 
    return binascii.hexlify(s) 
 
def hex2str(h): 
    return binascii.unhexlify(h) 
 
def main(): 
    # I don't want to type 200+ chars to test this :-) 
    hexstring = ''.join(random.choices(string.ascii_letters, k=201)) 
    hexstring = hexstring.encode('utf-8') 
    if len(hexstring) > 200: 
        hexstring = zlib.compress(hexstring) 
    print(hexstring) 
    hexstring = str2hex(hexstring) 
    ph = hexstring.decode('utf-8') 
    print(ph) 
 
    # decompressing text 
    unhexsring = hex2str(hexstring) 
    # Checking for 'x' in the string isn't a good way to check for  
    # compression. Try decoding first and if that fails we know we have  
    # compressed text.  
    try: 
        unhexsring = unhexsring.decode('utf-8') 
    except UnicodeDecodeError: 
        print('compressed') 
        unhexsring = zlib.decompress(unhexsring).decode('utf8') 
    print(unhexsring) 
 
if __name__ == '__main__': 
    main()