Python中将字节字符串转换为字典时遇错误求助
解决解密后字符串无法转换为字典的问题
看起来你遇到的核心问题是解密后的字符串格式不标准,导致不管用eval、ast.literal_eval还是json.loads都无法正确解析。咱们一步步来排查和解决:
1. 先定位问题根源
先别急着替换引号,先打印出解密后的原始字符串(decrypted.decode("UTF-8")),看看它的真实结构。你提到在IP地址最后一位报错,大概率是这个IP地址在字符串里没有被当成字符串处理——比如它是写成192.168.1.1而不是"192.168.1.1"。
这种情况下:
eval/ast.literal_eval会把192.168.1.1当成数字,但Python不允许数字有多个小数点,直接报语法错误;- 替换单引号成双引号后,
json.loads同样会把192.168.1.1当成无效的JSON值(JSON里没有这种格式的数字),所以也报错。
2. 最优解决方案:从源头规范数据格式
最好的办法是加密前就把字典转换成标准JSON字符串,这样解密后直接用json.loads解析,完全不需要手动替换引号,也不会有格式问题。
加密时的正确写法示例:
import json from cryptography.fernet import Fernet # 假设你的会话数据是这样的字典,注意IP必须是字符串(带引号) session_data = { "host": "192.168.1.1", "port": 22, "user": "admin", "password": "your_password" } # 把字典转成标准JSON字符串 json_data = json.dumps(session_data) # 加密JSON字符串的字节形式 fernet = Fernet(key) encrypted_data = fernet.encrypt(json_data.encode("UTF-8")) # 保存加密后的数据到文件 with open('saved_data.txt', 'wb') as f: f.write(encrypted_data)
解密时的对应写法:
def FileDecryption(): with open('enc_key.key', 'rb') as filekey: key = filekey.read() fernet = Fernet(key) with open('saved_data.txt', 'rb') as enc_file: encrypted = enc_file.read() decrypted = fernet.decrypt(encrypted) # 直接解析JSON字符串,无需替换引号 data = json.loads(decrypted.decode("UTF-8")) print(type(data)) # 这里会输出 <class 'dict'> for key in data: print(key) # 后续可以正常使用data里的内容
3. 修复已有的加密数据(如果没法重新加密)
如果已经有加密好的数据,没法重新生成,那我们需要先修复解密后的字符串格式,给没有引号的IP地址加上引号,再处理:
import re import json def FileDecryption(): with open('enc_key.key', 'rb') as filekey: key = filekey.read() fernet = Fernet(key) with open('saved_data.txt', 'rb') as enc_file: encrypted = enc_file.read() decrypted = fernet.decrypt(encrypted) raw_string = decrypted.decode("UTF-8") # 用正则给所有IP地址加上双引号 fixed_string = re.sub(r'(\d+\.\d+\.\d+\.\d+)', r'"\1"', raw_string) # 替换单引号成双引号,符合JSON格式要求 fixed_string = fixed_string.replace("'", '"') try: data = json.loads(fixed_string) print(type(data)) for key in data: print(key) except json.JSONDecodeError as e: print(f"解析错误:{e}") # 这里可以打印fixed_string,看看还有哪些格式问题 print("修复后的字符串:", fixed_string)
这个正则表达式会匹配所有类似xxx.xxx.xxx.xxx的IP格式,给它们加上双引号,解决核心的语法错误。如果还有其他格式问题(比如多余的逗号、括号不匹配),可以根据打印的fixed_string进一步调整。
内容的提问来源于stack exchange,提问作者sosumi
相关产品推荐
相关产品推荐

