Я совершенно смущен концепцией кодирования символов.
Что такое Unicode, GBK и т.д.? Как язык программирования использует их?
Нужно ли мне беспокоиться о них? Есть ли более простой или быстрый способ программирования, не беспокоясь о них?
Я совершенно смущен концепцией кодирования символов.
Что такое Unicode, GBK и т.д.? Как язык программирования использует их?
Нужно ли мне беспокоиться о них? Есть ли более простой или быстрый способ программирования, не беспокоясь о них?
(Обратите внимание, что я использую некоторые из этих условий свободно/разговорно для более простого объяснения, которое по-прежнему попадает в ключевые моменты.)
Байт может содержать только 256 различных значений, составляющих 8 бит.
Так как в наборе символов есть наборы символов с более чем 256 символами, то обычно нельзя сказать, что каждый символ является байтом.
Следовательно, должны быть сопоставления, описывающие, как превратить каждый символ в набор символов в последовательность байтов. Некоторые символы могут отображаться в один байт, но другие должны отображаться в несколько байтов.
Эти сопоставления являются кодировками, потому что они сообщают вам, как кодировать символы в последовательности байтов.
Что касается Unicode, на очень высоком уровне Unicode - это попытка присвоить каждому уникальному номеру уникальный номер. Очевидно, что это число должно быть чем-то большим, чем байт, так как имеется более 256 символов:) Java использует версию Unicode, где каждому символу назначается 16-битное значение (и поэтому символы Java имеют ширину 16 бит и имеют целочисленные значения от 0 до 65535). Когда вы получаете представление байта символа Java, вы должны указать JVM кодировку, которую вы хотите использовать, чтобы она знала, как выбрать последовательность байтов для символа.
Первоначально 1 символ всегда хранился как 1 байт. Байт (8 бит) может различать 256 возможных значений. Но на самом деле использовались только первые 7 бит. Таким образом, было определено только 128 символов. Этот набор известен как набор символов ASCII.
0x00
- 0x1F
содержат коды рулевого управления (например, CR, LF, STX, ETX, EOT, BEL,...)0x20
- 0x40
содержат числа и знаки препинания0x41
- 0x7F
содержат в основном буквенные символы0x80
- 0xFF
8-й бит = undefined.Французский, немецкий и многие другие языки нуждались в дополнительных персонажах. (например, à, é, ç, ô, ...
), которые не были доступны в наборе символов ASCII. Поэтому они использовали 8-й бит для определения своих символов. Это то, что известно как " расширенный ASCII".
Проблема заключается в том, что дополнительный 1 бит не имеет достаточной емкости для охвата всех языков в мире. Поэтому каждый регион имеет свой вариант ASCII. Существует много расширенных кодировок ASCII (latin-1
является очень популярным).
Популярный вопрос: "Является ли ASCII набором символов или это кодировка" ? ASCII
- это набор символов. Однако в программировании charset
и encoding
дико используются как синонимы. Если я хочу обратиться к кодировке, содержащей только символы ASCII и ничего больше (восьмой бит всегда равен 0): US-ASCII
.
Unicode также является набором символов (а не кодировкой). Он использует те же символы, что и стандарт ASCII, но расширяет список с дополнительными символами, что дает каждому символу код в формате u+xxxx
. У него есть цель содержать все символы (и популярные значки), используемые во всем мире.
UTF-8, UTF-16 и UTF-32 - это кодировки, которые применяют таблицу символов Unicode. Но каждый из них имеет несколько иной способ их кодирования. UTF-8 будет использовать только 1 байт при кодировании символа ASCII, давая тот же результат, что и любая другая кодировка ASCII. Но для других символов он будет использовать первый бит, чтобы указать, что последует второй байт.
GBK - это кодировка, которая, как и UTF-8, использует несколько байтов. Первый байт следует стандарту ASCII, поэтому используются только 7 бит. 8-й бит используется для указания наличия 2-го байта, который используется для представления около 22 000 иероглифов. Но важным отличием является то, что этот не учитывает набор символов Unicode.
Типы Mime также часто смешиваются с кодировками.
Нет простого способа декодирования файла. Было бы идеально, если бы все файлы содержали префикс, чтобы указать, в какой кодировке были сохранены их данные. В конце концов, это зависит от приложения (или его разработчика) для определения кодирования (например, US-ASCII
, UTF-8
, некоторые системные значения по умолчанию...).
При отправке данных через Интернет существует одна и та же проблема. К счастью, некоторые протоколы, такие как HTTP, используют объявления типа mime, чтобы указать, какие данные и кодировка используют данные. Типичный HTTP-заголовок содержит следующее:
Content-Type: text/html; charset=utf-8
Но для text/xml
это было бы бессмысленно (параметр charset будет даже проигнорирован). XML-синтаксисы вообще будут читать первую строку файла, ища тег <?xml encoding=...
.. Если он там, то они снова откроют файл, используя эту кодировку.
Та же проблема существует при отправке сообщений электронной почты. Электронная почта может содержать html-сообщение или простой текст.
В случае Java (и многих других языков программирования) в дополнение к опасностям кодирования существует также сложность литья байтов и целых чисел в символы, поскольку их содержимое хранится в разных диапазонах.
-128
до 127
).char
в java хранится в двух неподписанных байтах (диапазон: 0
- 65535
)-1
до 255
.Если вы знаете, что ваши данные содержат только значения ASCII. Затем с надлежащим навыком вы можете анализировать свои данные от байтов до символов или немедленно их переносить в Строки.
// the -1 indicates that there is no data
int input = stream.read();
if (input == -1) throw new EOFException();
// bytes must be made positive first.
byte myByte = (byte) input;
int unsignedInteger = myByte & 0xFF;
char ascii = (char)(unsignedInteger);
Ярлык в java - это использование читателей и писателей и указание кодировки при их создании.
// wrap your stream in a reader.
// specify the encoding
// The reader will decode the data for you
Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
Как объяснялось ранее для файлов XML, это не имеет большого значения, поскольку любой достойный маркер DOM или JAXB проверяет атрибут кодирования.
Кодировка символов - это то, что вы используете для решения проблемы написания программного обеспечения для тех, кто использует другой язык, чем вы.
Вы не знаете, что такое персонажи и как они упорядочены. Поэтому вы не знаете, что строки на этом новом языке будут выглядеть в двоичном и откровенном виде, вам все равно.
У вас есть способ перевода строк с языка, на котором вы говорите, на язык, на котором они говорят (скажем, переводчик). Теперь вам нужна система, способная представлять оба языка в двоичном формате без конфликтов. Кодировка - это система.
Это позволяет писать программное обеспечение, которое работает независимо от того, как языки представлены в двоичном формате.