#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 → Й
Комментариев нет:
Отправить комментарий