Хорошие ресурсы для изучения различных типов кодировки символов и преобразования между ними
-
05-07-2019 - |
Вопрос
Одна вещь, которую я никогда по-настоящему не понимал, - это концепция кодировки символов.То, как кодирование обрабатывается в памяти и коде, часто сбивает меня с толку тем, что я просто копирую пример из Интернета, не понимая по-настоящему, что он делает.Я чувствую, что это действительно важная и часто упускаемая из виду тема, и большему количеству людей следует потратить время на то, чтобы разобраться в ней правильно (включая меня).
Я ищу несколько хороших, по существу, ресурсов для изучения различных типов кодировки символов и преобразования между ними (предпочтительно на C #).Приветствуются как книги, так и онлайн-ресурсы.
Спасибо.
Правка 1:
Спасибо за ответы на данный момент.Я особенно ищу дополнительную информацию о том, как .NET обрабатывает кодирование.Я знаю, это может показаться расплывчатым, но я действительно не знаю, о чем просить.Я предполагаю, что мне любопытно, как кодировка представлена, скажем, в классе C # string и может ли сам класс управлять различными типами кодирования или для этого существуют отдельные классы?
Решение
Я бы начал с этого вопроса: что такое персонаж?
- Логическая идентичность:a кодовая точка.Unicode присваивает номер каждому символу, который не обязательно связан с какой-либо битовой формой.Кодировки (например, UTF-8) определяют сопоставление с байтовыми значениями.
- Биты и байты:в закодированная форма.Один или несколько байтов на кодовую точку, значения определяются используемой кодировкой.
- То, что вы видите на экране:a графема.Графема создается из одной или нескольких кодовых точек.Это материал, содержащийся в конце презентации.
Этот код преобразует in.txt
От windows-1252
Для UTF-8
и сохраняет его как out.txt
.
using System;
using System.IO;
using System.Text;
public class Enc {
public static void Main(String[] args) {
Encoding win1252 = Encoding.GetEncoding(1252);
Encoding utf8 = Encoding.UTF8;
using(StreamReader reader = new StreamReader("in.txt", win1252)) {
using(StreamWriter writer = new StreamWriter("out.txt", false, utf8)) {
char[] buffer = new char[1024];
while(reader.Peek() > 0) {
int r = reader.Read(buffer, 0, buffer.Length);
writer.Write(buffer, 0, r);
}
}
}
}
}
Здесь происходят два преобразования.Во-первых, байты декодируются из windows-1252
Для UTF-16
(маленький эндиан, я думаю) в char
буфер.Затем буфер преобразуется в UTF-8
.
Кодовые точки
Некоторые примеры кодовых точек:
- U+0041 - это ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА A (А)
- U+00A3 - это ЗНАК ФУНТА (£)
- U+042F равен КИРИЛЛИЧЕСКАЯ ЗАГЛАВНАЯ БУКВА YA (Я)
- U+1D50A равен МАТЕМАТИЧЕСКИЙ ФРАКТУРНЫЙ КАПИТАЛ G (𝔊)
Кодировки
Где бы вы ни работали с символами, они будут в кодировке той или иной формы.C # использует UTF-16 для своих тип символа, который он определяет как 16 бит шириной.
Вы можете думать о кодировке как о табличном отображении между кодовыми точками и байтовыми представлениями.
CODEPOINT UTF-16BE UTF-8 WINDOWS-1252
U+0041 (A) 00 41 41 41
U+00A3 (£) 00 A3 C2 A3 A3
U+042F (Ya) 04 2F D0 AF -
U+1D50A D8 35 DD 0A F0 9D 94 8A -
В Система.Текст.Кодировка класс предоставляет типы / методы для выполнения преобразований.
Графемы
Графема, которую вы видите на экране, может быть построена из более чем одной кодовой точки.Символ e-острый (é) может быть представлен двумя кодовыми точками, ЛАТИНСКАЯ МАЛЕНЬКАЯ БУКВА E U+0065 и СОЧЕТАНИЕ ОСТРОГО АКЦЕНТА U+0301.
('é' чаще всего представляется одной кодовой точкой U+00E9.Вы можете переключаться между ними с помощью нормализации.Однако не все комбинирующие последовательности имеют односимвольный эквивалент.)
Выводы
- Когда вы кодируете строку C # в кодировку, вы выполняете преобразование из UTF-16 в эту кодировку.
- Кодирование может быть преобразованием с потерями - большинство кодировок, отличных от Юникода, могут кодировать только подмножество существующих символов.
- Поскольку не все кодовые точки могут поместиться в один символ C #, количество символов в строке может быть больше, чем количество кодовых точек, а количество кодовых точек может быть больше, чем количество отображаемых графем.
- "Длина" строки зависит от контекста, поэтому вам нужно знать, какое значение вы применяете, и использовать соответствующий алгоритм.То, как это обрабатывается, определяется используемым вами языком программирования.
- Присвоение символам Latin-1 идентичных значений во многих кодировках вводит некоторых людей в заблуждение относительно ASCII.
(Это немного более многословно, чем я намеревался, и, вероятно, больше, чем вы хотели, поэтому я остановлюсь.Я написал еще более многословный сообщение о кодировке Java находится здесь.)
Другие советы
В Википедии есть довольно хорошее объяснение кодировки символов в целом: http://en.wikipedia.org/wiki/Character_encoding.
Если вы ищете подробную информацию о UTF-8, которая является одной из самых популярных кодировок символов, вам следует прочитать Часто ЗАДАВАЕМЫЕ ВОПРОСЫ по UTF-8 и Unicode.
И, как уже было указано, "Абсолютный минимум, который абсолютно, положительно должен знать каждый разработчик программного обеспечения О Unicode и наборах символов (никаких оправданий!)" это очень хороший учебник для начинающих.
Есть знаменитая статья Джоэла "Абсолютный минимум, который абсолютно, безусловно должен знать каждый разработчик программного обеспечения о Unicode и наборах символов (никаких оправданий!)". http://www.joelonsoftware.com/articles/Unicode.html
Редактировать:Хотя это больше касается текстовых форматов, при перечитывании, я полагаю, вас больше интересуют такие вещи, как кодировка html и URL-адреса?Которые предназначены для экранирования специальных символов, которые имеют значимые значения в html или URL-адресах (например < и > в html, или ?и = в URL-адресах)