Почему английские символы требуют меньше байтов для представления, чем другие алфавиты?


31

Когда я помещаю «a» в текстовый файл, он делает его 2 байта, но когда я помещаю, скажем, «ա», который является буквой армянского алфавита, он делает его 3 байта.

В чем разница между алфавитами для компьютера?
Почему английский занимает меньше места?


22
Вам следует прочитать эту статью основателя StackExchange: joelonsoftware.com/articles/Unicode.html
Эрик Липперт,

22
Я не думаю, что есть такая вещь, как «английские символы». Они римляне.
Рафаэль

5
@ Рафаэль, все знают, о чем он говорит. Но приятно добавить.
Матиас Ликкегор Лоренцен,

1
@Raphael На самом деле существует много латинских букв, которые не используются в английском языке и, следовательно, не включены в набор символов ASCII. Большинство из них включают модификаторы, но они все еще необходимы для правильной визуализации текста в различных латинских языках, отличных от английского.
Утаз

7
@ Рафаэль Я не думаю, что есть такая вещь, как «римские символы». Они латинские.
Blacklight Shining

Ответы:


41

Одной из первых схем кодирования, которая будет разработана для использования в основных компьютерах, является стандарт ASCII ( американский стандартный код для обмена информацией ). Он был разработан в 1960-х годах в Соединенных Штатах.

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

1960-е годы также были временем, когда у компьютеров не было того объема памяти или дискового пространства, который есть у нас сейчас. ASCII был разработан, чтобы быть стандартным представлением функционального алфавита на всех американских компьютерах. В то время решение сделать каждый символ ASCII длиной 8 бит (1 байт) было принято из-за технических деталей времени (в статье в Википедии упоминается тот факт, что перфорированная лента удерживала 8 бит в позиции за раз). Фактически, оригинальная схема ASCII может быть передана с использованием 7 битов, восемь могут быть использованы для проверок четности. Более поздние разработки расширили исходную схему ASCII, включив в нее несколько акцентированных, математических и терминальных символов.

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

Unicode пришел как решение для существования различных терминалов, объединяя все возможные значимые символы в один абстрактный набор символов.

UTF-8 - это один из способов кодирования набора символов Unicode. Это кодирование переменной ширины (например, разные символы могут иметь разные размеры), и оно было разработано для обратной совместимости с прежней схемой ASCII. Таким образом, набор символов ASCII останется одним байтом большого размера, в то время как любые другие символы имеют два или более байтов большого размера. UTF-16 - это еще один способ кодирования набора символов Unicode. По сравнению с UTF-8 символы кодируются как набор из одной или двух 16-битных кодовых единиц.

Как указано в комментариях, символ «а» занимает один байт, а символ «ա» занимает два байта, обозначая кодировку UTF-8. Дополнительный байт в вашем вопросе был связан с существованием символа новой строки в конце (о котором узнал ОП).


26
Не существует последнего байта, который кодирует конец файла, в любой обычной кодировке или формате файла. Когда программа читает файл, ОС может сообщить об окончании файла особым образом, но это другая проблема.
Юкка К. Корпела

2
Символ ա составляет 2 байта (0xD5A1) в версии Unicode UTF-8; дополнительный символ (что есть) присутствует в обоих файлах. marathon-studios.com/unicode/U0561/Armenian_Small_Letter_Ayb
Дэн Нили

6
@khajvah Если вы echo 'ա' > file.txtэто сделаете или отредактируете файл с помощью некоторых редакторов, они автоматически добавят после него новую строку. Если вы запустите xxd file.txt, последний байт, вероятно, будет 0a, или перевод строки.
Даниэль Бек

7
@DoktoroReichard: Пожалуйста, уточните в ответе, что Unicode не является кодировкой; скорее это абстрактный набор символов, а UTF-16 и UTF-8 являются кодировками кодовых точек Unicode. Последние абзацы вашего ответа в основном говорят о UTF-8. Но если файл использует UTF-16, то любая кодовая точка, даже одна для a, будет использовать два байта (или кратно двум).
grawity

6
Также, вероятно, стоит подчеркнуть, что наборы расширенных символов ASCII на самом деле вообще не являются ASCII, а количество различных способов использования восьмого бита делает все это большим беспорядком. Просто используйте вместо UTF-8.
ntoskrnl

17

1 байт равен 8 битам и может, таким образом, представлять до 256 (2 ^ 8) различных значений.

Для языков, которые требуют больше возможностей, чем это, простое сопоставление 1: 1 не может поддерживаться, поэтому для хранения символа требуется больше данных.

Обратите внимание, что в большинстве кодировок используются первые 7 бит (128 значений) для символов ASCII . Это оставляет 8-й бит или еще 128 значений для большего количества символов. , , добавьте акцентированные символы, азиатские языки, кириллицу и т. д., и вы легко поймете, почему 1 байт недостаточно для хранения всех символов.


так что вот единственный ответ, фактически объясняющий, почему используется больше места
Феликс Ганьон-Гренье

10

В UTF-8 символы ASCII используют один байт, другие символы используют два, три или четыре байта.


1
Можете ли вы объяснить, почему это так? отметить, что два метода кодирования не совсем отвечают на вопрос.
MaQleod

@MaQleod Unicode был создан, чтобы заменить ASCII. Для обратной совместимости первые 128 символов одинаковы. Эти 128 символов могут быть выражены одним байтом. Дополнительные байты добавляются для дополнительных символов.
Джейсон

Я знаю, но это часть ответа на вопрос о том, что отличает символы ASCII. Это следует объяснить ОП.
MaQleod

@MaQleod Можно также сказать, что Консорциум Unicode в основном состоял из американских корпораций и был склонен к английским символам. Я думал, что простой ответ лучше субъективного.
Джейсон

15
Не "в Unicode", в UTF8 - который является лишь одним из нескольких кодировок набора символов Unicode.
Себастьян Неграсус

3

Количество байтов, необходимое для символа (о чем, очевидно, вопрос), зависит от кодировки символов. Если вы используете кодировку ArmSCII, каждая армянская буква занимает всего один байт. Это не очень хороший выбор в наши дни.

В кодировке передачи UTF-8 для Unicode символам требуется различное количество байтов. В нем «а» занимает всего один байт (идея о двух байтах - своего рода путаница), «а» - два байта, а армянская буква айб «ա» - тоже два байта. Три байта должны быть какой-то путаницей. Напротив, например, бенгальская буква «অ» занимает три байта в UTF-8.

Фоном просто является то, что UTF-8 был разработан, чтобы быть очень эффективным для символов Ascii, довольно эффективным для систем письма в Европе и окрестностях, а все остальное менее эффективно. Это означает, что для базовых латинских букв (из которых в основном состоит английский текст) для символа требуется только один байт; для греческого, кириллического, армянского и некоторых других необходимо два байта; все остальное нужно больше.

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


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

1
Я не думаю, что UTF-8 был так разработан для эффективности с данными ASCII, как для совместимости . UTF-8 обладает очень хорошим свойством, заключающимся в том, что 7-битный контент ASCII (со старшим битом, установленным в ноль) идентичен тому же контенту, закодированному как UTF-8, поэтому для инструментов, которые обычно имеют дело с ASCII, это замена вставки , Насколько мне известно, никакая другая схема кодирования Unicode не обладает таким свойством. UTF-8 также достаточно компактен для большинства данных, особенно если вы остаетесь в области Unicode BMP .
CVn

1
@ MichaelKjörling, я добавил ссылку на эту функцию. Тем не менее, основным возражением против Unicode в первые дни была неэффективность, и UTF-16 удваивает размер данных, которые преимущественно являются Ascii. UTF-8 означает, например, для текста на английском языке, что вы «платите» только за те символы, которые не используются в Ascii.
Юкка К. Корпела

3

Коды символов в 1960-х (и не только) были машинно-специфическими. В 1980-х годах я кратко использовал машину DEC 2020, которая имела 36-битные слова и 5, 6 и 8 ( IIRC ) бит на кодировку символов. До этого я использовал IBM 370 серии с EBCDIC. ASCII с 7 битами привел порядок, но он получил путаницу с «кодовыми страницами» IBM PC, использующими все 8 битов для представления дополнительных символов, например всевозможные рисования блоков для рисования примитивных меню, и более поздние расширения ASCII, такие как Latin-1 (8 бит кодировки, с первыми 7 битами, такими как ASCII, и второй половиной для «национальных символов», таких как ñ, Çили др. Вероятно, наиболее популярной была Latin-1, адаптированная для английского и большинства европейских языков с использованием латинских символов (а также ударений и вариантов).

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

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


2

Windows 8.1 US / English Файл с одним «а», сохраненный в блокноте.

  • Сохранить как ANSI 1 байт
  • Сохранить как Unicode 4 байта
  • Сохранить как UTF-8 4 байта

Файл с одним «ա» сохранен в блокноте

  • Сохранить как ANSI невозможно
  • Сохранить как Unicode 4 байта
  • Сохранить как UTF-8 5 байт

Единственное «a» кодируется как один байт в ANSI, в Unicode каждый символ обычно составляет 2 байта, также есть 2-байтовая спецификация (Marker Order Marker) в начале файла. UTF-8 имеет 3-байтовую спецификацию и однобайтовый символ.

Для «ա» этот символ не существует в наборе символов ANSI и не может быть сохранен на моем компьютере. Файл Unicode такой же, как и раньше, а файл UTF-8 на 1 байт больше, поскольку символ занимает 2 байта.

Если ваш компьютер находится в другом регионе, у вас может быть установлена ​​другая кодовая страница OEM, которая имеет различные глифы для 255 символов, возможных в диапазоне ASCII. Как упомянул @ntoskrnl, кодовой страницей OEM для моей машины будет Windows-1252, которая используется по умолчанию для американского английского языка.


4
Блокнот (и Windows в целом) использует здесь запутанную терминологию. «ANSI» - это зависящая от локали однобайтовая кодировка (Windows-1252 в английских версиях), а «Unicode» - это UTF-16.
ntoskrnl

@ntoskrnl Это правильно, но если вы ищете в поле ввода для кодирования, оно говорит ANSI, именно поэтому я упомянул, если у вас другая кодовая страница OEM, вы можете получить другие результаты.
Дэррил Браатен

2

Если вас интересует, как хранятся символы, вы можете зайти на сайт www.unicode.org и осмотреться. Вверху их главной страницы находится ссылка «Кодовые таблицы», в которой показаны все коды символов, доступные в Юникоде.

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

Вместо этого Unicode обычно хранится в кодировке «UTF-8», которая использует меньше байтов для одних символов и больше для других. Первые 128 кодовых значений хранятся в одном байте, до первых 2048 кодовых значений хранятся в двух байтах, до 65536 хранятся в трех байтах, а остальные занимают четыре байта. Это было организовано так, что значения кода, которые используются чаще, занимают меньше места. AZ, az, 0-9 и! @ $% ^ & * () - [} {}; ': "|,. / <>? И некоторые, которые я забыл, берут один байт; почти весь английский, 98% Немецкий и французский (только догадка) могут храниться в одном байте на символ, и эти символы используются чаще всего: кириллица, греческий, иврит, арабский и некоторые другие используют два байта на символ. Индийские языки, большинство китайских, японские Корейский, тайский, тонны математических символов, может быть записано в трех байтах на символ. Редкие вещи (если вы когда-нибудь захотите написать текст в Linear A или Linear B, Emojis) занимают четыре байта.

Другая кодировка - UTF-16. Все, что занимает 1, 2 или 3 байта в UTF-8, занимает два байта в UTF-16. Это преимущество, если у вас есть китайский или японский текст с очень небольшим количеством латинских символов между ними.

О причинах дизайна UTF-8: у него есть несколько преимуществ перед другими конструкциями. Они есть:

Совместимость с символами US-ASCII

Разумная компактность

Самосинхронизация: это означает, что если вам дана часть последовательности байтов, которые являются символами в кодировке UTF-8, вы можете узнать, где начинается символ. В некоторых кодировках xy и yx могут быть допустимыми кодировками символов, поэтому, если вам дана часть последовательности ... xyxyxyxyxyxy ... вы не можете знать, какие символы у вас есть.

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

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

Плюс по любым причинам я забыл.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.