#java #utf_8 #encoding #cp1251
Берем строку "Игра!" и переводим в массив байт (1). Создаём строку, из этого массива байт, но указываем "неверную" кодировку(2). В итоге получаем строку с "поехавшей кодировкой"(utf8AsW1251 ). Выполняем обратные действия(3). и видим что строка переконвертировалась нормально за исключение большой буквы "И". Почему большая буква "И" отображается как �? ? import java.nio.charset.Charset; public class Main { private static final Charset CS_1251 = Charset.forName("windows-1251"); private static final Charset CS_UTF8 = Charset.forName("UTF-8"); public static void main(String[] args) { String in = "Игра!"; byte[] bytesUtf8 = in.getBytes(CS_UTF8); //(1) String utf8AsW1251 = new String(bytesUtf8, CS_1251); //(2) System.out.println("utf8 bytes as 1251: " + utf8AsW1251); //utf8 bytes as 1251: Р�РіСЂР°! System.out.println( new String(utf8AsW1251.getBytes(CS_1251), CS_UTF8) //(3) ); //�?гра! } }
Ответы
Ответ 1
– Доктор, когда я делаю так, у меня болит – Не делайте так Буква И кодируется в utf-8 как последовательность байтов 0xd0, 0x98 Код 0xd0 соответствует символу Р в кодировке cp1251, а вот код 0x98 не соответствует никакому символу, он просто отсутствует в кодировке, поэтому вместо несуществующего символа будет подставлен заменяющий. Получится строка Р�. Cимвол � тоже отсутсвует в cp1251, поэтому при повторном кодировании будет заменен на ? (с кодом 0x3f), получаем последовательность байтов 0xd0, 0x3f. При декодировании сталкиваемся еще с одной проблемой: последовательность 0xd0, 0x3f недопустима в utf-8, поэтому теперь уже вместо 0xd0 будет подставлен заменяющий символ, в итоге получается строка �? С остальными буквами такого может и не произойти, но это не значит, что подобные манипуляции всегда будут приводить к правильному результату Й → 0xd0, 0x99 → Р™ → 0xd0, 0x99 → Й
Комментариев нет:
Отправить комментарий