Как декодировать строку, которая была UTF-8 закодирована дважды в простой UTF-8?

у меня есть огромная таблица MySQL, которая имеет свои строки, закодированные в UTF-8 дважды. Например, "Újratárgyalja" хранится как "Újratárgyalja".

MySQL .Net connector загружает их таким образом. Я пробовал много комбинаций с System.Text.Encoding.Convert() но ни один из них не работал.

отправка set names 'utf8' (или другая кодировка) не решит его.

Как я могу декодировать их из double UTF-8 в UTF-8?

3 ответов


своеобразная проблема, но я думаю, что могу воспроизвести ее подходящим-нечестивым сочетанием UTF-8 и Latin-1 (а не только двумя использованием UTF-8 без перемежающегося неправильного шага на латыни-1). Вот вся странная поездка туда и обратно, "туда и обратно" (Python 2.* или IronPython должны быть в состоянии воспроизвести это):

# -*- 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

Это интересный выход...:

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

странная строка, начинающаяся с Ã появляется как enc2, т. е. две кодировки utf-8 С вкрапленная латынь-1 декодирование бросили в смесь. И, как вы можете видеть, его можно отменить с помощью точно обратной последовательности операций: декодировать как utf-8, перекодировать как latin-1, снова декодировать как utf-8-и исходная строка возвращается (yay!).

Я считаю, что обычные свойства туда и обратно как Latin-1 (aka ISO-8859-1), так и UTF-8 должны гарантировать, что эта последовательность будет работать (извините, нет C# , чтобы попробовать на этом языке прямо сейчас, но я ожидал бы, что кодирование / декодирование последовательности не должны зависеть от конкретного используемого языка программирования).


когда вы пишете " MySQL .Net connector загружает их таким образом."есть хороший шанс, что это означает, что MySQL .Net connector считает, что он говорит на латыни-1 с MySQL, в то время как MySQL считает, что разговор находится в UTF-8. Существует также вероятность, что столбец объявлен как Latin-1, но на самом деле содержит данные UTF-8.

Если это последний (столбец с надписью Latin-1, но данные на самом деле UTF-8), вы получите загадочные проблемы сортировки и другие ошибки, если вы используете текст MySQL функции обработки, порядок по столбцу или другие ситуации, когда текст "что-то значит", а не просто байты, отправленные по проводу.

в любом случае вы должны попытаться исправить основную проблему, не в последнюю очередь потому, что это будет полная головная боль для тех, кто должен поддерживать систему в противном случае.


вы можете попробовать использовать

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

на уровне запросов MySQL. Это удар в темноте.