Хорошие ресурсы для изучения различных типов кодировки символов и преобразования между ними - PullRequest
2 голосов
/ 11 сентября 2009

Одна вещь, которую я никогда не понимал, - это концепция кодирования символов. То, как кодирование обрабатывается в памяти, и код часто сбивает с толку меня тем, что я просто копирую пример из Интернета, не понимая, что он делает. Я чувствую, что это действительно важный и очень недооцененный вопрос, что все больше людей должны уделять время, чтобы получить права (в том числе и я).

Я ищу некоторые хорошие, точнее, ресурсы для изучения различных типов кодирования символов и преобразования между ними (предпочтительно в C #). Приветствуются как книги, так и онлайн-ресурсы.

Спасибо.


Редактировать 1:

Спасибо за ответы до сих пор. Я особенно ищу дополнительную информацию о том, как .NET обрабатывает кодирование. Я знаю, что это может показаться расплывчатым, но я не знаю, о чем просить. Я предполагаю, что мне любопытно, как кодирование представлено, скажем, в строковом классе C # и может ли сам класс управлять различными типами кодирования, или есть отдельные классы для этого?

Ответы [ 3 ]

2 голосов
/ 11 сентября 2009

В Википедии есть довольно хорошее объяснение кодировки символов в целом: http://en.wikipedia.org/wiki/Character_encoding.

Если вы ищете подробности о UTF-8, который является одним из самых популярных кодировок символов, вам следует прочитать UTF-8 и Unicode FAQ .

И, как уже указывалось, «Абсолютный минимум, который должен знать каждый разработчик программного обеспечения, абсолютно положительно знающий о юникоде и наборах символов (никаких оправданий!)» - очень хорошее руководство для начинающих.

2 голосов
/ 11 сентября 2009

Я бы начал с этого вопроса: что такое персонаж?

  • Логическая идентификация: кодовая точка . Unicode назначает число каждому символу, которое не обязательно связано с какой-либо битовой / байтовой формой. Кодировки (например, UTF-8) определяют отображение в байтовые значения.
  • Биты и байты: кодированная форма . Один или несколько байтов на кодовую точку, значения определяются используемой кодировкой.
  • То, что вы видите на экране: графема . Графема создается из одной или нескольких кодовых точек. Это материал в конце презентации.

Этот код преобразует 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.

* 1033 кодовые *

Некоторые примеры кодовых точек:

  • U + 0041 - ПИСЬМО ЛАТИНСКОГО КАПИТАЛА (A)
  • U + 00A3 - ЗВУКОВЫЙ ЗНАК (£)
  • U + 042F - это ПИСЬМО КИРИЛЛИЧЕСКОГО КАПИТАЛА YA (& # x042F;)
  • U + 1D50A - это МАТЕМАТИЧЕСКИЙ КАПИТАЛ FRAKTUR G (& # x1D50A;)

Кодировка

Где бы вы ни работали с персонажами, он будет в какой-то кодировке. C # использует UTF-16 для своего типа char , который он определяет как 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                -

Класс System.Text.Encoding предоставляет типы / методы для выполнения преобразований.

графемы

Графема, которую вы видите на экране, может состоять из нескольких кодов. Символ e-sharp (& # x0065; & # x0301;) может быть представлен двумя кодовыми точками: МАЛЕНЬКОЕ ЛАТИНСКОЕ ПИСЬМО E U + 0065 и КОМБИНИРОВАННЫЙ ОСТРЫЙ АКЦЕНТ U + 0301.

('& # x00E9;' чаще всего представляется одной кодовой точкой U + 00E9. Вы можете переключаться между ними с помощью нормализации. Однако не все последовательности объединения имеют одинаковый символьный эквивалент.)

Выводы

  • Когда вы кодируете строку C # в кодировку, вы выполняете преобразование из UTF-16 в эту кодировку.
  • Кодирование может быть преобразованием с потерями - большинство кодировок не в Юникоде может кодировать только подмножество существующих символов.
  • Поскольку не все кодовые точки могут вписываться в один символ C #, число символов в строке может превышать количество кодовых точек, а количество кодовых точек может превышать количество отображаемых графем.
  • «Длина» строки зависит от контекста, поэтому вам нужно знать, что вы применяете, и использовать соответствующий алгоритм. Как это обрабатывается, определяется используемым вами языком программирования.
  • Присвоение одинаковым значениям символов Latin-1 во многих кодировках дает некоторым людям заблуждение ASCII.

(Это немного более многословно, чем я хотел, и, вероятно, больше, чем вы хотели, поэтому я остановлюсь. Я написал еще более многословный пост о кодировке Java здесь .)

1 голос
/ 11 сентября 2009

Есть знаменитая статья Джоэла "Абсолютный минимум, который должен знать каждый разработчик программного обеспечения, абсолютно, положительно знающий о Unicode и наборах символов (никаких оправданий!)" http://www.joelonsoftware.com/articles/Unicode.html

Редактировать: Хотя это больше о текстовых форматах, я думаю, что при повторном чтении вас больше интересуют такие вещи, как HTML-кодирование и URL-кодирование? Предназначены для экранирования специальных символов, имеющих важное значение в HTML или URL (например, <и> в HTML или? И = в URL)

...