ValueError: encurtido de cadena inseguro

Cuando bash cargar algo que volqué con cPickle, aparece el mensaje de error:

ValueError: insecure string pickle 

Tanto el trabajo de descarga como el de carga se realizan en la misma computadora, por lo tanto, el mismo sistema operativo: Ubuntu 8.04.

¿Cómo podría resolver este problema?

“son mucho más probables que un error nunca observado en Python en una funcionalidad que se usa miles de millones de veces al día en todo el mundo”: siempre me sorprende cómo las personas cruzadas entran en estos foros.

Una manera fácil de resolver este problema es olvidando cerrar la secuencia que está utilizando para volcar la estructura de datos. Lo acabo de hacer

 >>> out = open('xxx.dmp', 'w') >>> cPickle.dump(d, out) >>> k = cPickle.load(open('xxx.dmp', 'r')) Traceback (most recent call last): File "", line 1, in  ValueError: insecure string pickle 

Por eso vine aquí en primer lugar, porque no podía ver lo que había hecho mal.
Y luego realmente lo pensé, en lugar de simplemente venir aquí, y me di cuenta de que debería haber hecho:

 >>> out = open('xxx.dmp', 'w') >>> cPickle.dump(d, out) >>> out.close() # close it to make sure it's all been written >>> k = cPickle.load(open('xxx.dmp', 'r')) 

Fácil de olvidar. No necesitaba que le dijeran a la gente que son idiotas.

Compruebe este hilo . Peter Otten dice:

Un pepinillo corrompido. El error se genera si una cadena en el volcado no comienza ni termina con “o”.

y muestra una forma sencilla de reproducir tal “corrupción”. Steve Holden, en la publicación de seguimiento, sugiere que otra manera de causar el problema sería desajustar ‘rb’ y ‘wb’ (pero en Python 2 y en Linux ese error en particular debería pasar inadvertido).

He recibido este error en Python 2.7 debido al modo abierto ‘rb’:

  with open(path_to_file, 'rb') as pickle_file: obj = pickle.load(pickle_file) 

Entonces, para Python 2 ‘modo’ debería ser ‘r’

Además, me he preguntado si Python 3 no es compatible con el formato pickle de Python 2, y en caso de que intentes cargar un archivo pickle creado en Python 2 obtendrás:

 pickle.unpicklingerror: the string opcode argument must be quoted 

¿Qué estás haciendo con los datos entre dump() y load() ? Es un error bastante común almacenar los datos decapados en un archivo abierto en modo de texto (en Windows) o en el almacenamiento de la base de datos de una manera que no funciona correctamente para los datos binarios (columnas VARCHAR, TEXT en algunas bases de datos, algunos almacenamientos de valores clave). Intente comparar los datos encurtidos que se pasan al almacenamiento y se recuperan de inmediato.

Si alguien tiene este error al usar youtube-dl , este problema tiene la solución: https://github.com/rg3/youtube-dl/issues/7172#issuecomment-242961695

richiecannizzo comentó el 28 de ago.

brew install libav
Debería arreglarlo instantáneamente en mac o

sudo apt-get install libav
#en linux

Este error también puede ocurrir con python 2 (y versiones anteriores de python 3) si su pickle es grande ( Python Issue # 11564 ):

 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: http://continuum.io/thanks and https://anaconda.org >>> import cPickle as pickle >>> string = "X"*(2**31) >>> pp = pickle.dumps(string) >>> len(pp) 2147483656 >>> ss = pickle.loads(pp) Traceback (most recent call last): File "", line 1, in  ValueError: insecure string pickle 

Esta limitación se abordó con la introducción del protocolo 4 de pickle en python 3.4 ( PEP 3154 ). Desafortunadamente, esta característica no se ha adaptado a Python 2, y probablemente nunca lo estará. Si este es su problema y necesita usar Python 2 pickle, lo mejor que puede hacer es reducir el tamaño de su pickle, por ejemplo, en lugar de escoger una list , los elementos de forma individual en una list de pickles.

El mismo problema con un archivo que se creó con Python en Windows y se volvió a cargar con Python en Linux. Solución: dos2unix en el archivo antes de leer en linux: ¡funciona como un encanto!

Recibí el Python ValueError: insecure string pickle de una manera diferente.

Para mí, sucedió después de que una base64 codificara un archivo binario y pasara a través de sockets urllib2 .

Inicialmente estaba envolviendo un archivo como este

 with open(path_to_binary_file) as data_file: contents = data_file.read() filename = os.path.split(path)[1] url = 'http://0.0.0.0:8080/upload' message = {"filename" : filename, "contents": contents} pickled_message = cPickle.dumps(message) base64_message = base64.b64encode(pickled_message) the_hash = hashlib.md5(base64_message).hexdigest() server_response = urllib2.urlopen(url, base64_message) 

Pero en el servidor, el hash seguía saliendo de forma diferente para algunos archivos binarios

 decoded_message = base64.b64decode(incoming_base64_message) the_hash = hashlib.md5(decoded_message).hexdigest() 

Y el despeje le dio un mensaje de insecure string pickle

 cPickle.loads(decoded_message) 

Pero el exito

Lo que funcionó para mí fue usar urlsafe_b64encode()

 base64_message = base64.urlsafe_b64encode(cPickle.dumps(message)) 

Y decodificar con

 base64_decoded_message = base64.urlsafe_b64decode(base64_message) 

Referencias

http://docs.python.org/2/library/base64.html

https://tools.ietf.org/html/rfc3548.html#section-3

Esto es lo que me pasó, podría ser una pequeña parte de la población, pero quiero poner esto aquí, sin embargo, para ellos:

El intérprete (Python3) le habría dado un error diciendo que requería que la secuencia del archivo de entrada estuviera en bytes, y no como una cadena, y es posible que haya cambiado el argumento de modo abierto de ‘r’ a ‘rb’, y ahora es diciéndote que la cadena está corrupta, y por eso has venido aquí.

La opción más sencilla para estos casos es instalar Python2 (puede instalar 2.7) y luego ejecutar su progtwig con el entorno Python 2.7, por lo que se deshace de su archivo sin problemas. Básicamente, perdí mucho tiempo explorando mi cadena para ver si estaba realmente corrupta cuando todo lo que tenía que hacer era cambiar el modo de abrir el archivo de rb a r, y luego usar Python2 para deshacer la búsqueda del archivo. Así que sólo estoy poniendo esta información por ahí.

Me encontré con esto antes, encontré este hilo y asumí que era inmune al problema de cierre de archivos mencionado en un par de estas respuestas ya que estaba usando una statement with :

 with tempfile.NamedTemporaryFile(mode='wb') as temp_file: pickle.dump(foo, temp_file) # Push file to another machine _send_file(temp_file.name) 

Sin embargo, como estaba presionando el archivo temporal desde adentro , el archivo aún no estaba cerrado, por lo que el archivo que estaba presionando se truncó. Esto dio como resultado el mismo error de insecure string pickle en el script que leyó el archivo en la máquina remota.

Dos posibles soluciones a esto: mantener el archivo abierto y forzar un vaciado:

 with tempfile.NamedTemporaryFile(mode='wb') as temp_file: pickle.dump(foo, temp_file) temp_file.flush() # Push file to another machine _send_file(temp_file.name) 

O asegúrese de que el archivo esté cerrado antes de hacer algo con él:

 file_name = '' with tempfile.NamedTemporaryFile(mode='wb', delete=False) as temp_file: file_name = temp_file.name pickle.dump(foo, temp_file) # Push file to another machine _send_file(file_name)