Что является основой для Unicode и зачем нужен UTF-8 или UTF-16? Я исследовал это в Google и искал здесь, но мне это не ясно.
В VSS при сравнении файлов иногда появляется сообщение о том, что два файла имеют разные UTF. Почему это так?
Пожалуйста, объясните в простых терминах.
Ответы:
Зачем нам нужен Юникод?
В (не слишком) первые дни все, что существовало, было ASCII. Это было хорошо, так как все, что когда-либо понадобилось, это несколько контрольных символов, знаки препинания, цифры и буквы, подобные тем, которые указаны в этом предложении. К сожалению, сегодняшний странный мир глобального общения и социальных сетей не предвиделся, и нередко видеть английский, английский, английский, английский и французский в том же документе (надеюсь, я не сломал старые браузеры).
Но ради аргумента, допустим, Джо Средний разработчик программного обеспечения. Он настаивает на том, что ему когда-либо понадобится только английский, и поэтому он хочет использовать только ASCII. Это может быть хорошо для пользователя Джо , но это не хорошо для разработчика программного обеспечения Джо . Приблизительно половина мира использует нелатинские символы, и использование ASCII для этих людей, возможно, неуместно, и, кроме того, он закрывает свое программное обеспечение для большой и растущей экономики.
Поэтому необходим всеобъемлющий набор символов, включающий все языки. Так появился Unicode. Каждому символу присваивается уникальный номер, называемый кодовой точкой . Одно из преимуществ Unicode над другими возможными наборами состоит в том, что первые 256 кодовых точек идентичны ISO-8859-1. и, следовательно, также ASCII. Кроме того, подавляющее большинство обычно используемых символов представлено только двумя байтами в области, называемой базовой многоязычной плоскостью (BMP) . Теперь для доступа к этому набору символов требуется кодировка символов, и, как задается вопрос, я сосредоточусь на UTF-8 и UTF-16.
Соображения памяти
Так сколько байтов дают доступ к каким символам в этих кодировках?
Теперь стоит упомянуть, что символы, отсутствующие в BMP, включают древние сценарии, математические символы, музыкальные символы и более редкие символы китайского / японского / корейского языков (CJK) .
Если вы будете работать в основном с символами ASCII, то UTF-8, безусловно, более эффективно использует память. Однако, если вы работаете в основном с неевропейскими сценариями, использование UTF-8 может потреблять до 1,5 раз меньше памяти, чем UTF-16. При работе с большими объемами текста, такими как большие веб-страницы или длинные текстовые документы, это может повлиять на производительность.
Основы кодирования
Примечание. Если вы знаете, как кодируются UTF-8 и UTF-16, перейдите к следующему разделу для практического применения.
1
должен избегать конфликтов с символами ASCII.Как видно, UTF-8 и UTF-16 далеко не совместимы друг с другом. Поэтому, если вы делаете ввод / вывод, убедитесь, что вы знаете, какую кодировку вы используете! Для получения более подробной информации об этих кодировках, пожалуйста, смотрите UTF FAQ .
Практические вопросы программирования
Символьные и строковые типы данных: как они кодируются на языке программирования? Если они являются необработанными байтами, в ту минуту, когда вы попытаетесь вывести символы, отличные от ASCII, вы можете столкнуться с несколькими проблемами. Кроме того, даже если тип символа основан на UTF, это не означает, что строки являются правильными UTF. Они могут разрешать байтовые последовательности, которые являются недопустимыми. Как правило, вам придется использовать библиотеку, которая поддерживает UTF, такую как ICU для C, C ++ и Java. В любом случае, если вы хотите ввести / вывести что-то отличное от кодировки по умолчанию, вам придется сначала преобразовать это.
Рекомендуемые / стандартные / доминантные кодировки: при выборе UTF, как правило, лучше всего следовать рекомендуемым стандартам для среды, в которой вы работаете. Например, UTF-8 является доминирующим в Интернете, а с HTML5 он была рекомендована кодировка . И наоборот, среды .NET и Java основаны на символьном типе UTF-16. Смущает (и неправильно), ссылки часто делаются на «кодировку Unicode», которая обычно относится к доминирующей кодировке UTF в данной среде.
Поддержка библиотек: используемые вами библиотеки поддерживают некоторую кодировку. Который из? Они поддерживают угловые дела? Поскольку необходимость является матерью изобретения, библиотеки UTF-8 обычно поддерживают должным образом 4-байтовые символы, поскольку часто могут встречаться 1, 2 и даже 3 байта. Однако не все предполагаемые библиотеки UTF-16 поддерживают суррогатные пары должным образом, поскольку они встречаются очень редко.
Подсчет символов: в Юникоде есть комбинируемые символы. Например, кодовая точка U + 006E (n) и U + 0303 (комбинированная тильда) образуют -, но кодовая точка U + 00F1 образует -. Они должны выглядеть одинаково, но простой алгоритм подсчета вернет 2 для первого примера, 1 для последнего. Это не обязательно неправильно, но может и не быть желаемым результатом.
Сравнение на равенство: A, А и Α выглядят одинаково, но они латинские, кириллические и греческие соответственно. У вас также есть такие случаи, как C и Ⅽ, один - буква, другой - римская цифра. Кроме того, у нас есть комбинации символов, которые необходимо учитывать. Для получения дополнительной информации см. Повторяющиеся символы в Юникоде .
Суррогатные пары: они встречаются достаточно часто на SO, поэтому я просто приведу несколько примеров ссылок:
Другие ?:
источник
источник
Поскольку заслуживающий доверия ресурс всегда нужен, но официальный отчет огромен, я предлагаю прочитать следующее:
Краткое объяснение:
Компьютеры читают байты, а люди читают символы, поэтому мы используем стандарты кодирования для сопоставления символов с байтами. ASCII был первым широко используемым стандартом, но охватывает только латиницу (7 бит / символ может представлять 128 различных символов). Unicode - это стандарт, цель которого - охватить все возможные символы в мире (может содержать до 1114 112 символов, то есть максимум 21 бит / символ. В настоящее время Unicode 8.0 содержит 120 737 символов, и все).
Основное отличие состоит в том, что символ ASCII может вписаться в байт (8 бит), но большинство символов Unicode не могут. Таким образом, используются формы / схемы кодирования (например, UTF-8 и UTF-16), и модель символов выглядит следующим образом:
Каждый символ занимает перечисляемую позицию от 0 до 1 114 111 (hex: 0-10FFFF), называемую кодовой точкой . Кодирующая форма отображает точку кода в код блока последовательности. Блок кода является способ , которым Вы хотите символы , которые будут организованы в памяти, 8-битных, 16-битных блоков и так далее. UTF-8 использует от 1 до 4 блоков по 8 битов, а UTF-16 использует 1 или 2 блока по 16 битов, чтобы охватить весь Unicode максимум из 21 бита. Единицы используют префиксы, чтобы можно было определить границы символов, и чем больше единиц, тем больше префиксов занимают биты. Таким образом, хотя UTF-8 использует 1 байт для латинского алфавита, ему требуется 3 байта для более поздних сценариев внутри базовой многоязычной плоскости, в то время как UTF-16 использует 2 байта для всех этих. И это их главное отличие. Наконец,
схема кодирования (например, UTF-16BE или UTF-16LE) отображает (сериализует) последовательность единиц кода в последовательность байтов.
символ: π
кодовая точка: U + 03C0
формы кодирования (кодовые единицы):
UTF-8: CF 80
UTF-16: 03C0
схемы кодирования (байты):
UTF-8: CF 80
UTF-16BE: 03 C0
UTF-16LE: C0 03
Совет: шестнадцатеричная цифра представляет 4 бита, поэтому шестнадцатеричное число, состоящее из двух цифр, представляет байт.
Также посмотрите на карты самолетов в Википедии, чтобы получить представление о расположении набора символов.
источник
Изначально Unicode должен был иметь 16-битное кодирование с фиксированной шириной (UCS-2). Первые пользователи Unicode, такие как Java и Windows NT, создавали свои библиотеки вокруг 16-битных строк.
Позже область действия Unicode была расширена и теперь включает в себя исторические символы, для чего потребуется более 65 536 кодовых точек, которые будет поддерживать 16-битное кодирование. Чтобы допустить представление дополнительных символов на платформах, которые использовали UCS-2, была введена кодировка UTF-16. Он использует «суррогатные пары» для представления символов в дополнительных плоскостях.
Между тем, многие старые программы и сетевые протоколы использовали 8-битные строки. UTF-8 был создан, чтобы эти системы могли поддерживать Unicode без использования широких символов. Он обратно совместим с 7-битным ASCII.
источник
Эта статья объясняет все детали http://kunststube.net/encoding/
ПИСЬМО В БУФЕР
если вы записываете в 4-байтовый буфер, символ
あ
с кодировкой UTF8, ваш двоичный файл будет выглядеть так:00000000 11100011 10000001 10000010
если вы записываете в 4-байтовый буфер, символ
あ
с кодировкой UTF16, ваш двоичный файл будет выглядеть так:00000000 00000000 00110000 01000010
Как вы можете видеть, в зависимости от того, какой язык вы будете использовать в своем контенте, это соответственно повлияет на вашу память.
Например, для этого конкретного символа:
あ
кодировка UTF16 более эффективна, поскольку у нас есть 2 свободных байта для следующего символа. Но это не значит, что вы должны использовать UTF16 для японского алфавита.ЧТЕНИЕ ИЗ БУФЕРА
Теперь, если вы хотите прочитать вышеупомянутые байты, вы должны знать, в какую кодировку он был записан, и правильно декодировать его обратно.
Например, если вы расшифруете это: 00000000 11100011 10000001 10000010 в кодировку UTF16, вы получите
臣
неあ
Примечание. Кодировка и Unicode - это две разные вещи. Unicode - это большой (таблица) с каждым символом, сопоставленным с уникальной кодовой точкой. Например,
あ
символ (буква) имеет (кодовую точку) : 30 42 (шестнадцатеричное). Кодирование, с другой стороны, представляет собой алгоритм, который преобразует символы более подходящим способом при хранении на аппаратном уровне.источник
Unicode - это стандарт, который отображает символы на всех языках в определенное числовое значение, называемое Code Points . Причиной этого является то, что он позволяет использовать разные кодировки с использованием одного и того же набора кодовых точек.
UTF-8 и UTF-16 являются двумя такими кодировками. Они принимают кодовые точки в качестве входных данных и кодируют их, используя некоторую четко определенную формулу для получения кодированной строки.
Выбор конкретной кодировки зависит от ваших требований. Разные кодировки имеют разные требования к памяти, и в зависимости от символов, с которыми вы будете иметь дело, вы должны выбрать кодировку, которая использует наименьшую последовательность байтов для кодирования этих символов.
Для более подробной информации о Unicode, UTF-8 и UTF-16, вы можете проверить эту статью,
Что каждый программист должен знать о Unicode
источник
Почему юникод? Потому что в ASCII всего 127 символов. Те от 128 до 255 отличаются в разных странах, поэтому есть кодовые страницы. Поэтому они сказали, что пусть до 1114111 символов. Итак, как вы храните самую высокую кодовую точку? Вам нужно будет хранить его с использованием 21 бита, поэтому вы будете использовать DWORD, имеющий 32 бита и потраченные 11 битов. Поэтому, если вы используете DWORD для хранения символа Юникода, это самый простой способ, потому что значение в вашем DWORD точно соответствует кодовой точке. Но массивы DWORD, конечно, больше, чем массивы WORD, и, конечно, даже больше, чем массивы BYTE. Вот почему существует не только UTF-32, но и UTF-16. Но utf-16 означает поток WORD, а WORD имеет 16 битов, так как же самая высокая кодовая точка 1114111 может вписаться в WORD? Оно не может! Поэтому они помещают все, что выше 65535, в DWORD, который они называют суррогатной парой. Такая суррогатная пара - это два слова, и их можно обнаружить, посмотрев на первые 6 бит. Так что насчет utf-8? Это байтовый массив или байтовый поток, но как самая высокая кодовая точка 1114111 может вписаться в байт? Оно не может! Ладно, они также вводят DWORD, верно? Или, возможно, СЛОВО, верно? Почти верно! Они изобрели последовательности utf-8, что означает, что каждая кодовая точка выше 127 должна быть закодирована в 2-байтовую, 3-байтовую или 4-байтовую последовательность. Вот Это Да! Но как мы можем обнаружить такие последовательности? Ну, все до 127 является ASCII и является одним байтом. То, что начинается с 110, является двухбайтовой последовательностью, то, что начинается с 1110, является трехбайтовой последовательностью, а то, что начинается с 11110, является четырехбайтовой последовательностью. Остальные биты этих так называемых «стартовых байтов» принадлежат кодовой точке. Теперь в зависимости от последовательности должны следовать следующие байты. Следующий байт начинается с 10, остальные биты представляют собой 6 битов полезной нагрузки и принадлежат кодовой точке. Объедините полезные биты начального байта и следующих байтов, и вы получите кодовую точку. Вот и вся магия UTF-8.
источник
ASCII - Программное обеспечение выделяет только 8-битный байт в памяти для данного символа. Это хорошо работает для английских и принятых символов (заимствованных слов, таких как фасад), так как их соответствующие десятичные значения падают ниже 128 в десятичном значении. Пример программы C.
UTF-8 - Программное обеспечение выделяет от 1 до 4 переменных 8-битных байтов для данного символа. Что здесь подразумевается под переменной? Допустим, вы отправляете символ «A» через ваши HTML-страницы в браузере (HTML - это UTF-8), соответствующее десятичное значение A равно 65, при преобразовании его в десятичное значение становится 01000010. Для этого требуется всего 1 байт. , 1 байтовая память выделяется даже для специальных принятых английских символов, таких как «ç» в слове «фасад». Однако, если вы хотите хранить европейские символы, требуется 2 байта, поэтому вам нужен UTF-8. Однако, когда вы выбираете азиатские символы, вам требуется минимум 2 байта и максимум 4 байта. Точно так же Emoji требуют от 3 до 4 байтов. UTF-8 решит все ваши потребности.
UTF-16 выделит минимум 2 байта и максимум 4 байта на символ, он не выделит 1 или 3 байта. Каждый символ представлен 16-битным или 32-битным.
Тогда почему существует UTF-16? Первоначально Unicode был 16 бит, а не 8 бит. Ява приняла оригинальную версию UTF-16.
Короче говоря, вам нигде не нужен UTF-16, если он не был принят языком или платформой, на которой вы работаете.
Java-программа, вызываемая веб-браузерами, использует UTF-16, но веб-браузер отправляет символы с использованием UTF-8.
источник
UTF расшифровывается как Unicode Transformation Format. В основном в современном мире существуют сценарии, написанные на сотнях других языков, форматы которых не охватываются базовым ASCII, использованным ранее. Следовательно, UTF появился на свет.
UTF-8 имеет возможности кодирования символов, и его кодовая единица составляет 8 бит, в то время как для UTF-16 это 16 бит.
источник