2009-09-19 18 views
6

Tengo una gran tabla MySQL que tiene dos filas codificadas en UTF-8. Por ejemplo, "Újratárgyalja" se almacena como "Újratárgyalja".¿Cómo decodificar una cadena que ha sido codificada UTF-8 dos veces a UTF-8 simple?

El conector .Net de MySQL las descarga de esta manera. Probé muchas combinaciones con System.Text.Encoding.Convert() pero ninguna funcionó.

Enviar set names 'utf8' (u otro juego de caracteres) no lo resolverá.

¿Cómo puedo decodificarlos desde el doble UTF-8 hasta el UTF-8?

+1

Tengo que votar esta pregunta, principalmente porque provocó la respuesta de Alex, que es bastante increíblemente ingeniosa. Además, la codificación puede ser un asunto complicado en general, ya que redescubrí solo experimentar con la respuesta de Alex en mi propia máquina. Tengo la sensación de que su enfoque podría ayudar (al menos como pista) en otros contextos de interoperabilidad también. –

Respuesta

8

Problema peculiar, pero creo que puedo reproducirlo con una mezcla no apropiada de UTF-8 y Latin-1 (no solo con dos usos de UTF-8 sin un paso incorrecto intercalado en Latin-1) . Aquí está todo el viaje redondo raro "y volver de nuevo" (Python 2. * o IronPython debe tanto ser capaces de reproducir este):

# -*- coding: utf-8 -*- 
uni = u'Újratárgyalja' 
enc1 = uni.encode('utf-8') 
enc2 = enc1.decode('latin-1').encode('utf-8') 
dec3 = enc2.decode('utf-8') 
dec4 = dec3.encode('latin-1').decode('utf-8') 

for x in (uni, enc1, enc2, dec3, dec4): 
    print repr(x), x 

Ésta es la salida interesante ...:

u'\xdajrat\xe1rgyalja' Újratárgyalja 
'\xc3\x9ajrat\xc3\xa1rgyalja' Újratárgyalja 
'\xc3\x83\xc2\x9ajrat\xc3\x83\xc2\xa1rgyalja' Ãjratárgyalja 
u'\xc3\x9ajrat\xc3\xa1rgyalja' Ãjratárgyalja 
u'\xdajrat\xe1rgyalja' Újratárgyalja 

La secuencia extraña que comienza con à aparece como enc2, es decir, dos codificaciones utf-8 CON una decodificación intercalada de latin-1 arrojada a la mezcla. Y como pueden ver, puede deshacerse mediante la secuencia de operaciones exactamente inversa: decodificar como utf-8, volver a codificar como latin-1, volver a decodificar como utf-8 de nuevo y la cadena original está de vuelta (yay !).

Creo que las propiedades normales de ida y vuelta de Latin-1 (también conocido como ISO-8859-1) y UTF-8 deberían garantizar que esta secuencia funcionará (lo siento, no hay C# para probar en ese idioma en este momento , pero esperaría que las secuencias de codificación/decodificación no dependan del lenguaje de programación específico en uso).

+0

Ingenioso. Y la respuesta es aceptada Sin embargo, por mi propia curiosidad, traté de reproducir tus resultados en Windows con Python 2.6.1. Tuvimos un momento difícil, porque el solo hecho de copiar y pegar el código creaba problemas (por ejemplo, pegar en el Bloc de notas y el editor IDLE eran bastante diferentes).Luego, la ejecución creó más problemas (tuvo que recurrir a imprimir solo repr (x) si estaba fuera de IDLE). [Lo sé, lo sé, obtengo un Sistema Operativo Real, etc.] –

-1

Usted podría tratar de usar

SELECT CONVERT(`your_column` USING ascii) 
FROM `your_table` 

a nivel de consulta MySQL. Sin embargo, esta es una puñalada en la oscuridad.

1

Cuando escribe "El conector .NET de MySQL las descarga de esta manera". hay una buena posibilidad de que esto signifique que el conector .Net de MySQL cree que está hablando Latin-1 a MySQL, mientras que MySQL cree que la conversación está en UTF-8. También existe la posibilidad de que la columna se declare como Latin-1, pero en realidad contiene datos UTF-8.

Si es la última (columna etiquetada Latin-1 pero los datos son realmente UTF-8) obtendrá misteriosos problemas de intercalación y otros errores si utiliza las funciones de procesamiento de texto de MySQL, ORDER BY en la columna u otras situaciones donde el texto "significa algo" en lugar de simplemente ser bytes enviados a través del cable.

En cualquier caso, debe intentar solucionar el problema subyacente, sobre todo porque va a ser un dolor de cabeza completo para quien tenga que mantener el sistema de otra manera.

+0

La columna está declarada como UTF-8 y los datos almacenados en ella también son UTF-8, pero por misteriosas razones, la extensión PDO de PHP la codificó dos veces. – RoliSoft

+0

Nunca mencionaste nada sobre PHP antes. Entonces, ¿los datos están realmente corruptos en la base de datos MySQL? – tialaramex

+0

Lo mencioné justo en la primera oración, que está almacenado en la base de datos MySQL de esa manera. Sin embargo, no mencioné que la extensión PDO de PHP los almacenaba de esta manera, porque la pregunta original era cómo decodificar una cadena en C# que ha sido codificada en UTF-8 dos veces. – RoliSoft