Говоря о компьютерном кодировании

задняя часть WeChat GitHub Unicode

Мы знаем, что внутри компьютера вся информация хранится в двоичном виде. Будь то символ или видео- и аудиофайл, в конечном итоге он будет соответствовать строке чисел, состоящей из 0 и 1. Следовательно, процесс преобразования человеческой информации, которую мы можем понять, в двоичный язык машинного уровня можно понимать как процесс кодирования.Естественно, противоположным процессом является так называемый процесс декодирования.

Вы могли бы выразить это так,Все они получены из мусора, несовместимого со схемой декодирования схемы кодирования.. Если я написал вам письмо по-английски (я хочу выразить информацию по-английски так [кодирование]а), а вы знаете только китайский язык, вы прочитали содержание письма по-китайски ([декодер] по-китайски), то весь письмо по-вашему является так называемым [искаженным]. На самом деле, так называемый мусор не является сложной проблемой, только то, что декодирование закодировано не так, как оно, до тех пор, пока в соответствующем режиме декодирования все в порядке.

Основываясь на истории развития компьютерного кодирования, от самой ранней кодировки ASCLL до метода кодирования Unicode в мире унифицированного кодирования, эта статья исследует, как наша [человеческая информация] кодируется в [информацию на уровне компьютера].

1. Всегда совместимый ASCLL

В середине прошлого века американцы изобрели компьютер, в то время они не считали, что популярность компьютеров будет такой быстрой, поэтому в то время американцы только сформулировали стандарт отображения между английскими символами и некоторыми управляющими символами и двоичный. Этот исходный стандарт, т. е.Стандарт кодирования ASCII.

ASCLL в первую очередь числа все символы, которые должны быть закодированы (всего 128 символов), например: количество числа 0 составляет 48, количество буквы A - 97 и т. Д. Таким образом, ascll использует байт (8 бит) для описания этих символов и преобразует их соответствующие номера из десятичных к двоичным. Таким образом, персонажи от 00000000 - 01111111 (0-127) устроены. Следовательно, когда все файлы с использованием стандарта кодирования ASCLL проанализированы, каждые восемь бита двоичных интерпретаций интерпретируются как символ, так что все английские символы, номера и другие символы могут храниться и прочитать. Классический стол ASCLL прилагается ниже:

image

Видно, что хотя в байте используется всего семь бит, но символов в нем все же достаточно много.Для американцев этого вполне достаточно, а вот для некоторых европейских стран, и даже нашего великого Китая, слишком мало байтов. , поэтому во многих странах региона есть свои расширенные стандарты кодирования, но они без исключения совместимы с кодировкой ASCLL (в конце концов, они и есть первооткрыватели).

2. Расширение Windows-1252 от европейцев

Американский стандарт ASCLL определяет метод кодирования только 128 символов, используя двоичный код сегмента интервала 00000000 -- 01111111. Таким образом, европейцы напрямую использовали 127 двоичных битов сегмента интервала 10000000 -- 11111111 (128-255) для определения некоторых своих собственных символов.

image
image

3. Расширение GB2312 от китайцев

В моей великой китайской нации тысячи китайских иероглифов, как может хорошо работать американский стандарт однобайтовой кодировки? GB2312 (код национального стандарта) в основном предназначен для упрощенного китайского языка, который мы часто используем в нашей повседневной жизни.Он содержит в общей сложности 6763 китайских символа.Он использует двухбайтовую кодировку и совместим со стандартом ASCLL.

Тогда есть проблема, стандартные символы ASCLL кодируются одним байтом, а наши китайские символы кодируются двумя байтами.При декодировании компьютер читает по одному байту и преобразует его по ASCLL.Стандартный разбор в один символ, или чтение двух байтов за раз и преобразование их в один китайский символ в соответствии с нашим стандартом GB2312?

GB2312 предопределяет двухбайтовую кодировку символов, старший бит первого байта должен быть равен 1. Таким образом, поскольку все символы ASCLL стандартны (00000000-01111111), старший бит равен 0, поэтому, когда компьютер считывает старший бит байта в 1, и даже два байта, прочитанные в соответствии со стандартом GB2312, анализируются как символ, или думайте, что это обычный символ, и следуйте ASCLL, чтобы разрешить его в обычный символ.

Ниже мы кратко опишем конкретные детали кода GB2312:

Прежде всего, GB2312 распределяет каждый китайский символ через так называемые [разделы].

  • Область 01-09 запрограммирована с некоторыми специальными символами
  • Области 16–55 располагают общеупотребительные китайские иероглифы первого уровня.
  • Области 56–87 располагают обычные китайские иероглифы второго уровня.
  • Области 00-15 и 88-94 не кодируются

Метод кодирования GB2312: 0xA0 + код города, 0xA0 + номер бита.Например: код города [Яна] — 4978 (78 бит в области 49), поэтому код Янга GB2312: 0xA0 + 49, 0xA0 + 78, а именно: D1EE.. Поэтому в прошлом существовал своего рода метод ввода местоположения, то есть набор текста выполняется путем ввода четырехзначных чисел, и эти четырехзначные числа являются номером местоположения китайского иероглифа. Насчет того, почему к коду города нужно добавлять 0xA0, я проверил много информации, но четкого утверждения нет, возможно, это регламент.

На самом деле, хорошенько подумайте.Разве так называемый процесс кодирования не является комбинацией двух шагов?, это важно понимать.

  • Используйте уникальный идентификатор для представления символа
  • Создайте единые правила для сопоставления идентификаторов с базовым двоичным файлом.

Стандарт ASCLL такой же, как и GB2312.

Например: ASCLL нумерует все символы, не повторяя друг друга (шаг 1), а затем формулирует правило, что двоичный код номера символа является его кодировкой (шаг 2).

Например: GB2312 присваивает номера разделов всем китайским иероглифам, не повторяя друг друга (первый шаг), а затем формулирует правила, чтобы через номера разделов можно было получить двоичные коды китайских иероглифов (второй шаг).

GBK обратно совместим и расширяет GB2312, включая китайские символы 21003. Он по-прежнему использует фиксированные два байта для кодирования китайских символов, но диапазон значений старших байтов другой, поэтому я не буду повторять их здесь.

4. Амбициозный Юникод

Выше мы представили американские стандарты кодирования, европейские стандарты кодирования и китайские стандарты кодирования.Конечно, это только верхушка айсберга.В мире существуют различные стандарты кодирования. Производители компьютеров в каждой стране должны использовать разные стандарты кодирования для производства компьютеров для разных регионов, что является громоздким и неэффективным. Существует ли стандарт кодирования, который может захватить все символы в мире и обеспечить реализацию хранения?

Рождение Unicode должно объединить все коды в мире.Он упорядочивает почти все символы в мире, в общей сложности почти более 1,1 миллиона наборов символов, а диапазон нумерации составляет от 0x000000 до 0x10FFFF. Но большинство символов находятся в диапазоне от 0x0000 до 0xFFFF (т. е. меньше 65536), каждый символ имеет номер Unicode и обычно представлен в шестнадцатеричном формате, которому предшествует U+. Например: Unicode-представление [Yang]: U+6768.

Юникод - это стандарт кодирования. Он просто нумерует все символы в мире и не определяет, как каждый символ и каждое число должны быть сопоставлены с двоичной строкой. Основными реализаторами Юникода являются: UTF-32, UTF-16 и UTF -8. Ниже мы рассмотрим конкретные детали реализации этих реализаторов.

1. УТФ-32

Это самая грубая реализация, она использует фиксированные четыре байта для хранения одного символа, а все символы хранятся в четырех байтах, что является пустой тратой места и редко используется в реальных условиях.

2. УТФ-16

Для реализации хранения Unicode следует придерживаться основной концепции: более часто используемые символы должны быть представлены меньшим количеством байтов, а более редкие символы должны быть представлены наибольшим количеством байтов. Давайте посмотрим на конкретные детали реализации UTF-16:

Диапазон кодирования Unicode составляет от 0x000000 до 0x10FFFF, всего можно запрограммировать 1 112 064 символа. Стратегия UTF-16 заключается в том, что диапазон чисел 0x00000 - 0x10000 (0-65532) является общим символом и хранится в двух фиксированных байтах. Среди них двоичное значение, соответствующее символу, представляет собой двоичное буквальное значение числа самого символа. Однако в пронумерованном диапазоне от 0xD800 до 0xDFFF символы не запрограммированы, и этот диапазон будет использоваться для последующего кодирования дополнительного набора символов, который здесь пока не упоминается.

Видно, что для общеупотребительных символов для кодирования используется два байта, но не общеупотребительное не означает, что их нельзя использовать. наборы, кодируются.

Для символов в диапазоне чисел 0x10000 — 0x10FFFF UTF-16 использует фиксированные четыре байта для хранения, но вы обнаружите, что общее количество символов FFFF находится между 0x10000 — 0x10FFFF, то есть 2^20 = 1 048 576 символов, т. е. , 20 бит необходимы для кодирования такого количества символов. Следовательно, в наших четырех байтах первые два байта имеют в общей сложности 16 бит, чтобы обеспечить как минимум 2 ^ 10 (111...111, десять один) возможностей, а последние два байта также предоставляют 2 ^ 10 возможностей. Если возможно, все дополнительные наборы символов могут быть объединены.

Однако теперь возникла проблема:Строка двоичных значений. Как определить, является ли символ обычным символом (хранящимся в фиксированных двух байтах) или дополнительным символом (хранящимся в четырех байтах)?

Решение для UTF-16 выглядит следующим образом:

Каждый символ имеет свой собственный номер Unicode Unicode, а для дополнительных символов их номера больше 0x10000. Вычитая число 0x10000 из самого символа, можно получить количество символов в наборе символов всех патчей. Это значение должно лежать в диапазоне чисел: 0x00000 - 0xFFFFF между ними, представляющими 20 бит, так как оставшееся число не более 0xFFFF является дополнительными символами.

Для первых двух байтов (называемых в Википедииведущий агент), определите их диапазон значений: от 0xD800 (0xD800 + 0x0000) до 0xDBFF (0xD800 + 0x3FF).[10 1 с]), что обеспечивает ровно 2^10 возможных значений.

Для последних двух байтов (называемых в Википедиизадний хвостовой прокси), также определяет их диапазон значений: от 0xDC00 (0xDC00 + 0x0000) до 0xDFFF (0xDC00 + 0x3FF).[10 1 с]), который также предоставляет ровно 2^10 возможных значений.

image

Поэтому, если обнаруживается, что двоичное значение первых двух байтов находится в диапазоне от 0xD800 до 0xDBFF, то это означает, что этот символ является добавочным и при кодировании хранится в четырех байтах фиксированно, а чтение четырех байтов поочередно Двоичное значение текущего символа. В противном случае это означает, что это базовый общий символ, хранящийся в двух фиксированных байтах, просто прочитайте два байта последовательно.

Вот несколько примеров:

1. Символы с номером Unicode U+0024.

Во-первых, определяется, что число меньше 0x10000, символ при использовании обычного набора символов, значение представляет собой закодированную бинарную форму UTF-16.

2. Символы с номером Unicode U+24B62.

Во-первых, оценивается, что числовое значение символа больше 0x10000, что указывает на принадлежность символа к дополнительному набору символов.

Итак, вычтите 0x10000 из 0x24B62, чтобы получить порядок символов в дополнительном наборе символов:0x14B62.

С помощью стандарта кодирования UTF-16 получаются начальный суррогат и замыкающий суррогат, и комбинация представляет собой кодировку символа UTF-16. Далее идет процесс расчета:

0x14B62 -> 0001 0100 1011 0110 0010

Начальный суррогат: 0001 0100 10 + 0xD800 = 0xD852

Заместитель хвоста поста: 11 0110 0010 + 0xDC00 = 0xDF62

Итак, кодировка UTF-16 символов U+24B62:0xD852 DF62

Подводя итог стандарту кодирования UTF-16, для символов с числами меньше 65536 в качестве закодированного значения двоичного числа используются фиксированные два байта. Для дополнительных наборов символов (числа больше 65536) сначала вычтите 65536 из собственного номера Unicode, чтобы получить порядковый номер текущего символа в дополнительном наборе символов, затем разделите два суррогата и добавьте определенные значения, чтобы они располагались в определенный диапазон, и используйте это, чтобы различать, хранится ли символ в двух байтах или в четырех байтах.

3. УТФ-8

UTF-8 (8-битный формат преобразования Unicode) — это кодировка символов переменной длины для Unicode. Символы Unicode кодируются с использованием от одного до четырех байтов, наиболее часто используемые символы хранятся с использованием наименьшего количества байтов, а редко используемые символы хранятся с использованием относительно небольшого количества байтов.

Правила кодирования UTF-8 показаны на следующем рисунке:

image

Для символов, число которых меньше 127, стандарт кодирования UTF-8 эквивалентен стандарту кодирования ASCLL.

Для остального диапазона чисел закодируйте его в соответствии с форматом, показанным на рисунке, и больше нечего сказать.Теперь давайте посмотрим, как он кодируется на примере.

Номер Unicode для китайского символа [ян]: 0x6768, десятичный: 26472.

Очевидно, что стандартный формат кодировки китайского символа UTF-8: 1110xxxx 10xxxxxx 10xxxxxx

Двоичный код 0x6768: 0110 0111 0110 1000

Начиная с последнего бита этого двоичного файла, замените [x] в формате кодирования сзади вперед.

image

Очевидно, результат вышел, и соответствующий ему шестнадцатеричный код:0xE69DA8

Подводя итог, можно сказать, что стандарт кодирования UTF-8 классифицирует все числа Unicode, и чем выше рейтинг, тем меньше байтов используется для хранения. Различные диапазоны нумерованных наборов символов Unicode будут иметь разные шаблоны при выполнении кодировки UTF-8.Используйте собственное двоичное число, чтобы установить шаблон в соответствии с соответствующими правилами, и вы можете получить соответствующую кодировку UTF-8.

Напротив, когда указан файл в кодировке UTF-8, когда компьютер декодирует его, наименьшая единица измерения — байты. Если старший бит текущего байта равен 0, выполните описанные выше шаги в обратном порядке, чтобы получить двоичную форму символа с номером Unicode, а затем просмотрите таблицу, чтобы получить символ.

Если в начале текущего байта их несколько, то единиц несколько, и закодированное двоичное значение символа имеет несколько байтов, которые можно читать последовательно. Тогда та же обратная операция, естественно, может получить соответствующие символы.

Здесь кратко представлены несколько распространенных методов кодирования.Что касается кодирования, всегда помните выводы, изложенные в этой статье.Все стандарты кодирования на самом деле делают две вещи: во-первых, присваивают номер или идентификатор всем символам, которые необходимо закодировать, и во-вторых, определяют правило для унифицированного сопоставления этого номера или идентификатора с двоичной строкой.


Весь код, изображения, файлы в статье хранятся в облаке на моем GitHub:

(https://github.com/SingleYam/overview_java)

Добро пожаловать в публичный аккаунт WeChat: Gorky on the code, все статьи будут синхронизированы в публичном аккаунте.

image