Я сам видел именно эту проблему, на самом деле. Короткий ответ: нет простого алгоритма. Но есть надежда.
Во-первых, по моему опыту, данные имеют тенденцию быть:
- 99% ASCII
- .9% UTF-8
- .1% другое, 75% из которых Windows-1252.
Так что давайте использовать это. Вы захотите проанализировать свой собственный набор данных, чтобы увидеть, соответствует ли он этому шаблону. (Я нахожусь в Америке, так что это типично. Я думаю, что БД, содержащая данные, основанные на Европе, может быть не такой удачной, а что-то еще дальше на восток - еще менее удачной.)
Во-первых, в большинстве современных кодировок в качестве подмножества содержится ASCII. UTF-8 делает, ISO-8859-1 делает, и т. Д. Таким образом, если поле содержит только октеты в диапазоне [0, 0x7F] (то есть, символы ASCII), то оно, вероятно, закодировано в ASCII / UTF-8 / ISO- 8859-1 / и т.д.. Если вы имеете дело с американским английским, это, вероятно, позаботится о 99% ваших данных.
На том, что осталось.
У UTF-8 есть несколько приятных свойств: он будет либо 1-байтовым ASCII-символом, либо ИЛИ все после первого байта будет 10xxxxxx
в двоичном виде. Итак: попытайтесь запустить оставшиеся поля через декодер UTF-8 (тот, который захлебнется, если вы дадите ему мусор.) По полям, которые он не захлебнулся, мой опыт показал, что они, вероятно, действительны в формате UTF-8. (Здесь можно получить ложный положительный результат: у нас может быть хитрое поле ISO-8859-1, которое также является допустимым UTF-8.)
Наконец, если это не ASCII, и он не декодируется как UTF-8, Windows-1252, похоже, является следующим хорошим выбором. Windows-1252 подходит практически для всех, поэтому здесь трудно получить ошибки.
Вы можете сделать это:
- Попытка декодирования как ASCII. В случае успеха предположим ASCII.
- Попытка декодирования как UTF-8.
- Попытка декодирования как Windows-1252
Для UTF-8 и Windows-1252 выведите PK таблицы и декодированный текст «угадай» в текстовый файл (перед выводом преобразуйте Windows-1252 в UTF-8). Посмотрите на это человеком, посмотрите, не увидят ли они что-нибудь неуместное. Если не слишком много данных, не относящихся к ASCII (и, как я уже сказал, ASCII имеет тенденцию доминировать, если вы в Америке ...), тогда человек может просмотреть все это.
Кроме того, если у вас есть представление о том, как выглядят ваши данные, вы можете ограничить декодирование определенными символами. Например, если поле декодируется как действительный текст UTF-8, но содержит «©», а поле является именем человека, то это, вероятно, ложный положительный результат, и к нему следует присмотреться более внимательно.
Наконец, имейте в виду, что при переходе на базу данных UTF-8 все, что вставляло эти мусорные данные в прошлом, вероятно, все еще там: вам нужно будет отследить эту систему и научить ее кодированию символов.