python-ValueError:不安全的字符串pi
当我尝试加载使用cPickle转储的内容时,出现错误消息:
ValueError: insecure string pickle
转储和加载工作都在同一台计算机上完成,因此在同一操作系统上:Ubuntu 8.04。
我该如何解决这个问题?
Peter Long asked 2020-06-20T09:33:20Z
10个解决方案
86 votes
“与Python本身从未见过的bug相比,在全世界每天使用数十亿次的功能中,这种错误的可能性要大得多”:它总是让我感到惊讶,跨平台的人如何进入这些论坛。
解决此问题的一种简单方法是忘记关闭用于转储数据结构的流。 我已经做了
>>> out = open('', 'w')
>>> (d, out)
>>> k = (open('', 'r'))
Traceback (most recent call last):
File "", line 1, in
ValueError: insecure string pickle
这就是为什么我首先来到这里的原因,因为我看不到自己做错了什么。
然后我实际上考虑了此事,而不是只是来这里,并意识到我应该这样做:
>>> out = open('', 'w')
>>> (d, out)
>>> () # close it to make sure it's all been written
>>> k = (open('', 'r'))
容易忘记。 不需要人们被告知他们是白痴。
Allan Ramsay answered 2020-06-20T09:33:48Z
9 votes
由于开放模式“ rb”,我在Python 2.7中遇到此错误:
with open(path_to_file, 'rb') as pickle_file:
obj = (pickle_file)
因此,对于Python 2,“模式”应为“ r”
另外,我想知道Python 3不支持Python 2的pickle格式,如果您尝试加载在Python 2中创建的pickle文件,则会得到:
: the string opcode argument must be quoted
Oleg Neumyvakin answered 2020-06-20T09:34:17Z
8 votes
检查该线程。 彼得·奥滕(Peter Otten)说:
泡菜坏了。 错误是 如果转储中的字符串确实发生,则引发 并非以“或”开头和结尾。
并显示了重现这种“腐败”的简单方法。 在后续文章中,史蒂夫·霍尔顿(Steve Holden)提出了另一种导致该问题的方法,即不匹配“ rb”和“ wb”(但是在Python 2和Linux中,该特殊错误应该忽略不计)。
Alex Martelli answered 2020-06-20T09:34:46Z
7 votes
您正在处理dump()和load()之间的数据吗? 将腌制的数据存储在以文本模式(在Windows上)中打开的文件中或数据库存储中,以对二进制数据不能正常工作的方式(VARCHAR,某些数据库中的TEXT列,某些键值存储)的方式存储,这是一个常见错误。 尝试比较传递给存储并立即从存储中检索的腌制数据。
Denis Otkidach answered 2020-06-20T09:35:06Z
7 votes
如果有人使用sudo apt-get install libav遇到此错误,则此问题已解决:[/rg3/youtube-dl/issues/7172#issuecomment-242961695]
要求评论评论于8月28日
sudo apt-get install libav
应该立即在Mac或
sudo apt-get install libav
#在Linux上
Pysis answered 2020-06-20T09:35:48Z
6 votes
如果您的泡菜很大(Python Issue#11564),则在python 2(和python 3的早期版本)中也可能发生此错误:
Python 2.7.11 |Anaconda custom (64-bit)| (default, Dec 6 2015, 18:08:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Anaconda is brought to you by Continuum Analytics.
Please check out: /thanks and
>>> import cPickle as pickle
>>> string = "X"*(2**31)
>>> pp = (string)
>>> len(pp)
2147483656
>>> ss = (pp)
Traceback (most recent call last):
File "", line 1, in
ValueError: insecure string pickle
通过在python 3.4(PEP 3154)中引入pickle协议4解决了此限制。 不幸的是,此功能尚未反向移植到python 2,并且可能永远不会移植到python 2。 如果这是您的问题,并且您需要使用python 2泡菜,则最好的方法是减小泡菜的大小,例如,而不是对list进行酸洗,而不是对元素进行酸洗,将其腌制为list。
Paul Price answered 2020-06-20T09:36:13Z
4 votes
在Windows上使用python制作的文件,在Linux上使用python重新加载的文件也存在同样的问题。解决方案:在Linux上阅读之前,先对文件上的dos2unix进行操作!
am_technix answered 2020-06-20T09:36:34Z
3 votes
我以另一种方式收到了urlsafe_b64encode()消息。
对我来说,它发生在urlsafe_b64encode()对二进制文件进行编码并通过urllib2套接字之后。
最初我是在包装这样的文件
with open(path_to_binary_file) as data_file:
contents = data_file.read()
filename = (path)[1]
url = 'http://0.0.0.0:8080/upload'
message = {"filename" : filename, "contents": contents}
pickled_message = (message)
base64_message = base64.b64encode(pickled_message)
the_hash = hashlib.md5(base64_message).hexdigest()
server_response = (url, base64_message)
但是在服务器上,对于某些二进制文件,哈希值以不同的方式出现
decoded_message = base64.b64decode(incoming_base64_message)
the_hash = hashlib.md5(decoded_message).hexdigest()
和解开给urlsafe_b64encode()消息
(decoded_message)
但是成功
对我有用的是使用urlsafe_b64encode()
base64_message = base64.urlsafe_b64encode((message))
并用
base64_decoded_message = base64.urlsafe_b64decode(base64_message)
参考文献
[HTTP:///2/library/巴塞]
[HTTPS:// /HTML/#section-3]
HeyWatchThis answered 2020-06-20T09:37:38Z
1 votes
这就是我所发生的事情,可能只是一小部分人,但是我还是想在这里为他们介绍一下:
解释器(Python3)会给您一个错误,指出它要求输入文件流以字节为单位,而不是字符串,并且您可能已将打开模式参数从'r'更改为'rb',现在是 告诉您字符串已损坏,这就是为什么您来这里。
在这种情况下,最简单的选择是安装Python2(可以安装2.7),然后在Python 2.7环境下运行程序,这样它就可以释放文件而不会出现问题。 基本上,当我要做的只是将打开文件的模式从rb更改为r,然后使用Python2解开文件时,我浪费了很多时间来查看字符串是否确实损坏。 所以我只是把这些信息放在那里。
Arijit answered 2020-06-20T09:38:08Z
0 votes
我较早地遇到了这个问题,找到了这个线程,并假设我不受几个答案中提到的文件关闭问题的影响,因为我使用的是with语句:
with (mode='wb') as temp_file:
(foo, temp_file)
# Push file to another machine
_send_file(temp_file.name)
但是,由于我是从with内部推送临时文件的,因此该文件仍未关闭,因此我推送的文件被截断了。 这导致在读取远程计算机上的文件的脚本中出现相同的insecure string pickle错误。
对此的两个潜在修复:保持文件打开并强制刷新:
with (mode='wb') as temp_file:
(foo, temp_file)
temp_file.flush()
# Push file to another machine
_send_file(temp_file.name)
或者在执行任何操作之前确保文件已关闭:
file_name = ''
with (mode='wb', delete=False) as temp_file:
file_name = temp_file.name
(foo, temp_file)
# Push file to another machine
_send_file(file_name)
0x5453 answered 2020-06-20T09:38:42Z