Setting the http charset parameter
Содержание:
- Encoding in base64
- Is it a ranking factor for SEO?
- Если кодировка не отображается
- Кодировки стандарта UNICODE
- Вводная информация
- C0 Controls
- Понимание Схем Кодирования
- How does it work?
- Importance of setting the correct MIME typeEDIT
- Другие Места, Где Кодирование Важно
- SyntaxEDIT
- HTML Tags
- Why is it important?
- Преобразование строки в массив байтов
- Где и как изменить кодировку
- Как определить кодировку на сайте
- Кодирование и декодирование
- Скалярные значения Юникода
Encoding in base64
Of course the code examples provided above don’t display the full data URI for any of the audio and video files as they would fill the entire page! To encode the data I simply used PHP‘s function as follows:
Which was used by the HTML:
Of course you can use whatever you like to encode the files, this is just an example. And while you may not want nor need to base64 encode your audio and video files (these reasons on why you might base64 encode images might be just as relevant), it’s still good to know that you can should the need arise.
The MIME type is the mechanism to tell the client the variety of document transmitted: the extension of a file name has no meaning on the web. It is, therefore, important that the server is correctly set up, so that the correct MIME type is transmitted with each document. Browsers often use the MIME-type to determine what default action to do when a resource is fetched.
There are many kinds of documents, so there are many MIME types. In this article, we will list the most important for Web development, but you can find ones for applicable document types in this dedicated article: Complete list of MIME types.
MIME types are not the only way to convey the document type information:
- Name suffixes are sometimes used, especially on Microsoft Windows systems. Not all operating systems consider these suffixes meaningful (especially Linux and Mac OS), and like an external MIME type, there is no guarantee they are correct.
- Magic numbers. The syntax of the different kind of files often allow to determine the type by looking at the structure. E.g. each GIF files starts with the 47 49 46 38 hexadecimal value or PNG files with 89 50 4E 47 . Not all types of files have magic numbers, so this is not a 100% reliable system either.
On the Web, only the MIME type is relevant and has therefore to be set carefully. Browsers and servers often used heuristics based on suffixes or magic numbers to define the MIME type, to check for coherence, or to find the correct MIME type when only a generic type has been provided.
Is it a ranking factor for SEO?
The character set is not a ranking factor for search engine optimization. Most search engines focus on the important goal of delivering relevant, useful content to those who seek it and as such does not consider other outside factors that do not contribute to that goal.
So your character set matters because of how you transmit information but search engines are not interested in it. Using other charsets apart from Utf-8 will not decrease your SEO ranking because to a large extent it doesn’t matter what character encoding you use as long as the search engine is able to get information to the end users.
Если кодировка не отображается
Если вы зашли на чужой сайт с абракадаброй, а вам все равно очень интересно почитать контент, то в Справке Google объясняют, как исправить кодирование текста через браузер.
О проблеме возникновения абракадабры на вашем сайте будут сигнализировать метрики поведения: вырастут отказы, уменьшится глубина просмотров. Но скорее всего вы и раньше заметите, что что-то пошло не так.
Главное правило — для всех файлов, скриптов, баз данных сайта и сервера должна быть указана одна кодировка. Ошибка может возникнуть, если вы случайно указали на сайте разные виды кодировки.
Яндекс советует использовать одинаковую кодировку для страниц и кириллических адресов структуры. К примеру, если робот встретит ссылку href=»/корзина» на странице с кодировкой UTF-8, он сохранит ее в этом же UTF-8, так что страница должна быть доступна по адресу «/%D0%BA%D0%BE%D1%80%D0%B7%D0%B8%D0%BD%D0%B0».
Кодировки стандарта UNICODE
Юникод (англ. Unicode) — стандарт кодирования символов, позволяющий представить знаки почти всех письменностей мира, и специальных символов. Представляемые в юникоде символы кодируются целыми числами без знака. Юникод имеет несколько форм представления символов в компьютере: UTF-8, UTF-16 (UTF-16BE, UTF-16LE) и UTF-32 (UTF-32BE, UTF-32LE). (Англ. Unicode transformation format — UTF).UTF-8 — это в настоящее время распространённая кодировка, которая нашла широкое применение в операционных системах и веб-пространстве. Текст, состоящий из символов Unicode с номерами меньше 128 (область с кодами от U+0000 до U+007F), содержит символы набора ASCII с соответствующими кодами. Далее расположены области знаков различных письменностей, знаки пунктуации и технические символы. Под символы кириллицы выделены области знаков с кодами от U+0400 до U+052F, от U+2DE0 до U+2DFF, от U+A640 до U+A69F.
Кодировка UTF-8 является универсальной и имеет внушительный резерв на будущее. Это делает ее наиболее удобной кодировкой для использования в интернете.
HTML Символы
Кодирование URL
Вводная информация
Важно обеспечить, чтобы любая информация о кодировке символов, отправленная сервером была правильной, так как информация в HTTP
заголовке переопределяет информацию в самом документе. Многие серверы Apache настроены, чтобы отправлять файлы с использованием кодировки ISO-8859-1 (Latin-1)
В примерах в этом документе, мы будем считать, что
вы хотите обслуживать ваш файл или файлы, используя другие кодировки, нежели указано в конфигурации по умолчанию. (Для получения консультации по выбору кодирования
смотрите Выбор и применение кодирования.)
Многие серверы Apache настроены, чтобы отправлять файлы с использованием кодировки ISO-8859-1 (Latin-1). В примерах в этом документе, мы будем считать, что
вы хотите обслуживать ваш файл или файлы, используя другие кодировки, нежели указано в конфигурации по умолчанию. (Для получения консультации по выбору кодирования
смотрите Выбор и применение кодирования.)
Ниже приведен пример HTTP заголовка, который сопровождает присланный к клиентскому приложению файл. В этом случае информация о кодировке символов
содержится в заголовке Content-Type во второй строке снизу.
HTTP/1.1 200 OK Date: Wed, 05 Nov 2003 10:46:04 GMT Server: Apache/1.3.28 (Unix) PHP/4.2.3 Content-Location: CSS2-REC.en.html Vary: negotiate,accept-language,accept-charset TCN: choice P3P: policyref=http://www.w3.org/2001/05/P3P/p3p.xml Cache-Control: max-age=21600 Expires: Wed, 05 Nov 2003 16:46:04 GMT Last-Modified: Tue, 12 May 1998 22:18:49 GMT ETag: "3558cac9;36f99e2b" Accept-Ranges: bytes Content-Length: 10734 Connection: close Content-Type: text/html; charset=utf-8 Content-Language: en
В примере заголовок Content-Type выражает как MIME тип файла так и кодировку символов. MIME тип описывает
формат файла, что обслуживался. HTML файлы, как правило, обслуживаются, как text/html. Кодировка символов (или ‘charset’)
этого файла — UTF-8.
Чтобы узнать, как просмотреть HTTP заголовок файла смотрите статью Проверка HTTP Заголовков.
Файлы на сервере Apache могут обслуживаться с кодировкой символов по умолчанию в HTTP заголовке, что конфликтует с фактическим
кодированием файла. Кодировка символов, отправляемая сервером может быть новой кодировкой по умолчанию, установленной по умолчанию администратором сервера, либо
результатом выполнения различных директив Apache. В других случаях никакую информацию о кодировке символов сервер не отправляет, когда она действительно
необходима.
C0 Controls
The control characters were originally designed to control
hardware devices.
Control characters (except horizontal tab, carriage return, and line feed)
have nothing to do inside an HTML document.
Char | Dec | Hex | Description |
---|---|---|---|
NUL | 0000 | null character | |
SOH | 1 | 0001 | start of header |
STX | 2 | 0002 | start of text |
ETX | 3 | 0003 | end of text |
EOT | 4 | 0004 | end of transmission |
ENQ | 5 | 0005 | enquiry |
ACK | 6 | 0006 | acknowledge |
BEL | 7 | 0007 | bell (ring) |
BS | 8 | 0008 | backspace |
HT | 9 | 0009 | horizontal tab |
LF | 10 | 000A | line feed |
VT | 11 | 000B | vertical tab |
FF | 12 | 000C | form feed |
CR | 13 | 000D | carriage return |
SO | 14 | 000E | shift out |
SI | 15 | 000F | shift in |
DLE | 16 | 0010 | data link escape |
DC1 | 17 | 0011 | device control 1 |
DC2 | 18 | 0012 | device control 2 |
DC3 | 19 | 0013 | device control 3 |
DC4 | 20 | 0014 | device control 4 |
NAK | 21 | 0015 | negative acknowledge |
SYN | 22 | 0016 | synchronize |
ETB | 23 | 0017 | end transmission block |
CAN | 24 | 0018 | cancel |
EM | 25 | 0019 | end of medium |
SUB | 26 | 001A | substitute |
ESC | 27 | 001B | escape |
FS | 28 | 001C | file separator |
GS | 29 | 001D | group separator |
RS | 30 | 001E | record separator |
US | 31 | 001F | unit separator |
DEL | 127 | 007F | delete (rubout) |
❮ Previous
Next ❯
Понимание Схем Кодирования
Кодировка символов может принимать различные формы в зависимости от количества символов, которые она кодирует.
Количество закодированных символов имеет прямое отношение к длине каждого представления, которое обычно измеряется как количество байтов. Наличие большего количества символов для кодирования по существу означает необходимость более длинных двоичных представлений.
Давайте рассмотрим некоторые из популярных схем кодирования на практике сегодня.
4.1. Однобайтовое кодирование
Одна из самых ранних схем кодирования, называемая ASCII (Американский стандартный код для обмена информацией), использует однобайтовую схему кодирования. По сути, это означает, что каждый символ в ASCII представлен семибитными двоичными числами. Это все еще оставляет один бит свободным в каждом байте!
Ascii 128-символьный набор охватывает английские алфавиты в нижнем и верхнем регистрах, цифры и некоторые специальные и контрольные символы.
Давайте определим простой метод в Java для отображения двоичного представления символа в определенной схеме кодирования:
String convertToBinary(String input, String encoding) throws UnsupportedEncodingException { byte[] encoded_input = Charset.forName(encoding) .encode(input) .array(); return IntStream.range(0, encoded_input.length) .map(i -> encoded_input) .mapToObj(e -> Integer.toBinaryString(e ^ 255)) .map(e -> String.format("%1$" + Byte.SIZE + "s", e).replace(" ", "0")) .collect(Collectors.joining(" ")); }
Теперь символ ” T ” имеет кодовую точку 84 в US-ASCII (ASCII в Java называется US-ASCII).
И если мы используем наш метод утилиты, мы можем увидеть его двоичное представление:
assertEquals(convertToBinary("T", "US-ASCII"), "01010100");
Это, как мы и ожидали, семиразрядное двоичное представление символа “T”.
Исходный ASCII оставил самый значимый бит каждого байта неиспользованным. В то же время ASCII оставил довольно много непредставленных символов,
Исходный ASCII оставил самый значимый бит каждого байта неиспользованным. || В то же время ASCII оставил довольно много непредставленных символов,
Было предложено и принято несколько вариантов схемы кодирования ASCII.
Многие расширения ASCII имели разные уровни успеха, но, очевидно, это
Одним из наиболее популярных расширений ASCII был ISO-8859-1 , также называемый “ISO Latin 1”.
4.2. Многобайтовое кодирование
Поскольку потребность в размещении все большего количества символов росла, однобайтовые схемы кодирования, такие как ASCII, не были устойчивыми.
Это привело к появлению многобайтовых схем кодирования, которые имеют гораздо большую емкость, хотя и за счет увеличения требований к пространству.
BIG 5 и SHIFT-JIS являются примерами многобайтовых схем кодирования символов, которые начали использовать как один, так и два байта для представления более широких наборов символов . Большинство из них были созданы для того, чтобы представлять китайские и аналогичные сценарии, которые имеют значительно большее количество символов.
Давайте теперь вызовем метод convertToBinary с вводом как “語”, китайский символ, и кодирование как “Big5”:
assertEquals(convertToBinary("語", "Big5"), "10111011 01111001");
Вывод выше показывает, что кодировка Big5 использует два байта для представления символа “語”.
полный список кодировок символов, наряду с их псевдонимами, ведется Международным органом по номерам.
How does it work?
Meta Charset is what determines how text is transmitted and stored. This text data is usually converted to binary first and then there needs to be a kind of cipher that connects characters with their correct binary equivalents.
When this data is eventually decoded, the character encoding must be known beforehand or there could be complications. An example of these can be seen in browsers when you’re looking at a webpage. Information about the kind of character set used comes from the server or is written directly by the developer. Unfortunately, there is a myriad of character sets and this means diverse ways of matching binary codes to characters and bytes.
For content developers and authors, choosing the UTF-8 character set for your content means that you can use a single character set to multiple characters needs thereby simplifying things greatly without the need to track and convert multiple times. This means it would be easier to surf through your content without getting confusing characters and garbage
Importance of setting the correct MIME typeEDIT
Most web servers send unknown-type resources using the default MIME type. For security reasons, most browsers do not allow setting a custom default action for such resources, forcing the user to store it to disk to use it. Some commonly seen incorrect server configurations happen with the following file types:
-
RAR-encoded files. In this case, the ideal would be to set the true type of the encoded files; this is often not possible (as it may not be known to the server and these files may contain several resources of different types). In this case, configuring the server to send the MIME type, users will not have defined a useful default action for them.
-
Audio and video files. Only resources with the correct MIME Type will be recognized and played in or elements. Be sure to use the correct type for audio and video.
-
Proprietary file types. Pay particular attention when serving a proprietary file type. Avoid using as special handling will not be possible: most browsers do not allow defining a default behavior (like «Opening in Word») for this generic MIME type.
Другие Места, Где Кодирование Важно
Нам не просто нужно учитывать кодировку символов при программировании. Тексты могут окончательно испортиться во многих других местах.
наиболее распространенной причиной проблем в этих случаях является преобразование текста из одной схемы кодирования в другую , что может привести к потере данных.
Давайте быстро рассмотрим несколько мест, где мы можем столкнуться с проблемами при кодировании или декодировании текста.
7.1. Текстовые Редакторы
В большинстве случаев текстовый редактор-это место, откуда исходят тексты. Существует множество текстовых редакторов в популярном выборе, включая vi, Блокнот и MS Word. Большинство из этих текстовых редакторов позволяют нам выбрать схему кодирования. Следовательно, мы всегда должны быть уверены, что они подходят для текста, с которым мы работаем.
7.2. Файловая система
После того, как мы создадим тексты в редакторе, нам нужно сохранить их в какой-то файловой системе. Файловая система зависит от операционной системы, на которой она работает. Большинство операционных систем имеют встроенную поддержку нескольких схем кодирования. Однако все еще могут быть случаи, когда преобразование кодировки приводит к потере данных.
7.3. Сеть
Тексты, передаваемые по сети с использованием протокола, такого как протокол передачи файлов (FTP), также включают преобразование между кодировками символов. Для всего, что закодировано в Юникоде, безопаснее всего передавать в двоичном виде, чтобы свести к минимуму риск потери при преобразовании. Однако передача текста по сети является одной из менее частых причин повреждения данных.
7.4. Базы данных
Большинство популярных баз данных, таких как Oracle и MySQL, поддерживают выбор схемы кодирования символов при установке или создании баз данных. Мы должны выбрать это в соответствии с текстами, которые мы ожидаем сохранить в базе данных. Это одно из наиболее частых мест, где повреждение текстовых данных происходит из-за преобразования кодировки.
7.5. Браузеры
Наконец, в большинстве веб-приложений мы создаем тексты и пропускаем их через различные слои с намерением просмотреть их в пользовательском интерфейсе, например в браузере
Здесь также важно, чтобы мы выбрали правильную кодировку символов, которая может правильно отображать символы. Большинство популярных браузеров, таких как Chrome, Edge, позволяют выбирать кодировку символов в своих настройках
SyntaxEDIT
General structure
type/subtype
The structure of a MIME type is very simple; it consists of a type and a subtype, two strings, separated by a . No space is allowed. The type represents the category and can be a discrete or a multipart type. The subtype is specific to each type.
A MIME type is insensitive to the case, but traditionally is written all in lower case.
Discrete types
text/plain text/html image/jpeg image/png audio/mpeg audio/ogg audio/* video/mp4 application/octet-stream …
Discrete types indicates the category of the document, it can be one of the following:
Type | Description | Example of typical subtypes |
---|---|---|
Represents any document that contains text and is theoretically human readable | , , | |
Represents any kind of images. Videos are not included, though animated images (like animated gif) are describes with an image type. | , , , , | |
Represents any kind of audio files | , | |
Represents any kind of video files | , | |
Represents any kind of binary data. | , , , , , |
For text documents without specific subtype, should be used. Similarly for binary documents without specific or known subtype, should be used.
Multipart types
multipart/form-data multipart/byteranges
Multipart types indicates a category of document that are broken in distinct parts, often with different MIME types. It is a way to represent composite document. With the exception of , that are used in relation of HTML Forms and method, and that are used in conjunction with status message to send only a subset of a whole document, HTTP doesn’t handle multipart documents in a specific way: the message is simply transmitted to the browser (which will likely propose a Save As window, not knowing how display the document inline.)
HTML Tags
<!—><!DOCTYPE><a><abbr><acronym><address><applet><area><article><aside><audio><b><base><basefont><bdi><bdo><big><blockquote><body><br><button><canvas><caption><center><cite><code><col><colgroup><data><datalist><dd><del><details><dfn><dialog><dir><div><dl><dt><em><embed><fieldset><figcaption><figure><font><footer><form><frame><frameset><h1> — <h6><head><header><hr><html><i><iframe><img><input><ins><kbd><label><legend><li><link><main><map><mark><meta><meter><nav><noframes><noscript><object><ol><optgroup><option><output><p><param><picture><pre><progress><q><rp><rt><ruby><s><samp><script><section><select><small><source><span><strike><strong><style><sub><summary><sup><svg><table><tbody><td><template><textarea><tfoot><th><thead><time><title><tr><track><tt><u><ul><var><video>
Why is it important?
When you think of the fact that every single time text is transmitted, it needs to be encoded in a specific charset and decoded on the other side, the importance of charset is quite obvious. This means that without proper character coding, a browser will display garbage text because it simply does not understand what is being put into it and has to make a quick uninformed guess.
It is also important in html forms because when you input text into text boxes on sites or social media platforms, it has to be encoded carefully. If this information is unavailable for any reason, the incorrect mapping could lead to the loss of vital information.
What a character set does is to provide a key to unlock and crack a code that passes between the user and the website.
It is a set of structured mappings between the bytes in the computer and the characters in the character set. If this key is missing, the data looks like written garbage. This means that when you input text through a keyboard, the character set links the characters you choose to specific bytes in computer memory, and then to display the text it reads the bytes back into the characters.
Преобразование строки в массив байтов
Иногда нам нужно преобразовать Строку в байт[] . Самый простой способ сделать это-использовать метод String getBytes() :
String originalInput = "test input"; byte[] result = originalInput.getBytes(); assertEquals(originalInput.length(), result.length);
String originalInput = "test input"; byte[] result = originalInput.getBytes(StandardCharsets.UTF_16); assertTrue(originalInput.length() < result.length);
Если наша строка Base64 закодирована, мы можем использовать декодер Base64 |:
String originalInput = "dGVzdCBpbnB1dA=="; byte[] result = Base64.getDecoder().decode(originalInput); assertEquals("test input", new String(result));
Мы также можем использовать DatatypeConverter parseBase64Binary() метод :
String originalInput = "dGVzdCBpbnB1dA=="; byte[] result = DatatypeConverter.parseBase64Binary(originalInput); assertEquals("test input", new String(result));
Наконец, мы можем преобразовать шестнадцатеричную строку в байт[] с помощью метода DatatypeConverter :
String originalInput = "7465737420696E707574"; byte[] result = DatatypeConverter.parseHexBinary(originalInput); assertEquals("test input", new String(result));
Где и как изменить кодировку
Все зависит от сайта. Способ установки кодировки может различаться: если используется одностаничник, то достаточно в HTML-файле прописать мета-тег в блоке <head>:
<meta charset="utf-8">
В противном случае нам потребуется отредактировать файл .htaccess. Рассмотрим на примере хостинга Timeweb, как это можно сделать.
- Открываем личный кабинет и переходим в раздел «Файловый менеджер». В нем перемещаемся в директорию с сайтом и находим в корне файл .htaccess – открываем его двойным кликом мыши.
- В начало файла необходимо добавить следующий код:
Для UTF-8: AddDefaultCharset UTF-8 Для Windows-1251: AddDefaultCharset WINDOWS-1251
Открываем свой сайт и видим, что ничего не изменилось – так и должно быть. Чтобы внести изменения, очищаем кэш с помощью комбинации клавиш «CTRL+F5» и смотрим результат.
Как видите, сменить кодировку на своем сайте легко. Аналогичным образом мы можем изменить кодировку и на всем сервере – для этого необходимо выполнить следующее (актуально для веб-сервера Apache):
- Находим файл httpd.conf, который расположен по адресу: «/usr/local/apache/conf/», и открываем его.
- Если нужно поменять Windows-1251 на UTF-8, то меняем строку «AddDefaultCharset windows-1251» на «AddDefaultCharset utf-8».
Если вы поменяете кодировку по умолчанию, то она будет изменена для всех ресурсов, находящихся на данном сервере.
Как определить кодировку на сайте
Определить кодировку страницы своего или чужого сайта можно через исходный код страницы. Откройте страницу сайта, выберите «Просмотр кода страницы» (сочетание горячих клавиш Ctrl+U» в Google Chrome) и найдите упоминание «charset» внутри тега head.
На странице сайта используется кодировка UTF-8:
Указание кодировки в коде страницы
Узнать вид кодирования можно с помощью «Анализа сайта». Сервис проверяет в том числе и техническую сторону ресурса: анализирует серверную информацию, определяет кодировку, проверяет редиректы и другие пункты.
Фрагмент анализа серверной информации сайта
С помощью этого же сервиса можно проверить корректность указанного кодирования. Аудит внутренних страниц «Анализа сайта» проверяет кодировку сервера и сравнивает ее с той, которая указана на внутренней странице. Найденные ошибки Анализ покажет в результатах проверки, и вы сразу узнаете, где нужно исправить.
Отчет о технических данных
Кодировка сервера и страницы
Проверить кодировку еще можно через сервис Validator.w3, о котором писали в статье о проверке валидации кода. Нужная надпись находится внизу страницы.
Кодировка сайта в валидаторе
Если валидатор не обнаружит Charset, он покажет ошибку:
Ошибка указания кодировки
Но валидатор работает не точно: он проверяет только синтаксис разметки, поэтому может не показать ошибку, даже если кодирование указано неправильно.
Кодирование и декодирование
Кодирование— это процесс формирования определенного представления информации,переход от одной формы представления информации к другой, более удобной для хранения, передачи или обработки.То есть любой символ, который мы видим или вводим, для компьютера в реальности — всего лишь набор битов (набор нулей и единиц). Именно эти биты и перегоняются от устройства к устройству. А чтобы показать результат этих перегонок человеку, компьютер преобразует с помощью таблицы (той самой кодировки) код символа в соответствующий внешний вид.
UTF-32LE в UTF-8
Схемой можете воспользоваться при кодировании и раскодировании.
Эта схема сделана так, чтобы вы видели какие биты куда попадают как при кодировании, так и раскодировании.
По ней видно что при этих обоих процессах просто нужные биты выставляются на нужные позиции при нужных значениях контрольных бит.
Можно заметить что компоновка в больших байтовых последовательностях осуществляется по 6 бит (в так называемых лидирующих байтах).
При этом старшие биты предусматриваемого кода будут в первых байтах (схоже с порядком Big-Endian).
Кодирование
Порядок действий такой:
- Каждый символ превращаем в Unicode.
- Проверяем из какого диапазона символ.
- Если код символа меньше 128, то к результату добавляем его в неизменном виде.
- Если код символа меньше 2048, то берем последние 6 бит и первые 5 бит кода символа. К первым 5 битам добавляем 0xC0 и получаем первый байт последовательности, а к последним 6 битам добавляем 0x80 и получаем второй байт. Конкатенируем и добавляем к результату.
- Похожим образом можем продолжить и для больших кодов, но если символ за пределами U+FFFF придется иметь дело с UTF-16 суррогатами.
Function EncodeUTF8(s)
Dim i, c, utfc, b1, b2, b3 For i=1 to Len(s) c = ToLong(AscW(Mid(s,i,1))) If c < 128 Then utfc = chr( c) ElseIf c < 2048 Then b1 = c Mod &h40 b2 = (c - b1) &h40 utfc = chr(&hC0 + b2) & chr(&h80 + b1) ElseIf c < 65536 And (c < 55296 Or c > 57343) Then b1 = c Mod &h40 b2 = ((c - b1) &h40) Mod &h40 b3 = (c - b1 - (&h40 * b2)) &h1000 utfc = chr(&hE0 + b3) & chr(&h80 + b2) & chr(&h80 + b1) Else ' Младший или старший суррогат UTF-16 utfc = Chr(&hEF) & Chr(&hBF) & Chr(&hBD) End If EncodeUTF8 = EncodeUTF8 + utfc Next End Function Function ToLong(intVal) If intVal < Then ToLong = CLng(intVal) + &H10000 Else ToLong = CLng(intVal) End If End Function
Декодирование
Декодирование — преобразование зашифрованной информации в понятный, пригодный для непосредственного использования вид.
- Ищем первый символ вида 11xxxxxx
- Считаем все последующие байты вида 10xxxxxx
- Если последовательность из двух байт и первый байт вида 110xxxxx, то отсекаем приставки и складываем, умножив первый байт на 0x40.
- Аналогично для более длинных последовательностей.
- Заменяем всю последовательность на нужный символ Unicode.
Function DecodeUTF8(s)
Dim i, c, n, b1, b2, b3 i = 1 Do While i <= len(s) c = asc(mid(s,i,1)) If (c and &hC0) = &hC0 Then n = 1 Do While i + n <= len(s) If (asc(mid(s,i+n,1)) and &hC0) <> &h80 Then Exit Do End If n = n + 1 Loop If n = 2 and ((c and &hE0) = &hC0) Then b1 = asc(mid(s,i+1,1)) and &h3F b2 = c and &h1F c = b1 + b2 * &h40 Elseif n = 3 and ((c and &hF0) = &hE0) Then b1 = asc(mid(s,i+2,1)) and &h3F b2 = asc(mid(s,i+1,1)) and &h3F b3 = c and &h0F c = b3 * &H1000 + b2 * &H40 + b1 Else ' Символ больше U+FFFF или неправильная последовательность c = &hFFFD End if s = left(s,i-1) + chrw( c) + mid(s,i+n) Elseif (c and &hC0) = &h80 then ' Неожидаемый продолжающий байт s = left(s,i-1) + chrw(&hFFFD) + mid(s,i+1) End If i = i + 1 Loop DecodeUTF8 = s End Function
Скалярные значения Юникода
Термин относится ко всем кодовым точкам, кроме суррогатных. Другими словами, скалярное значение — это любая кодовая точка, которой присвоен символ или которой может быть присвоен символ в будущем. Слово «символ» здесь относится ко всему, что может быть назначено кодовой точке, включая действия, которые определяют способ отображения текста или символов.
На приведенной ниже схеме показаны точки кода скалярного значения.
Тип Rune как скалярное значение
Начиная с версии .NET Core 3.0, тип System.Text.Rune представляет скалярное значение Юникода. Тип недоступен в .NET Core 2.x или .NET Framework 4.x.
Конструкторы проверяют, является ли полученный экземпляр допустимым скалярным значением Юникода. В противном случае они создают исключение. В следующем примере показан код, который создает экземпляры , так как входные данные представляют допустимые скалярные значения:
В следующем примере создается исключение, так как кодовая точка находится в суррогатном диапазоне и не является частью суррогатной пары:
В следующем примере создается исключение, так как кодовая точка находится за пределами дополнительного диапазона:
Пример использования Rune: изменение регистра букв
API, который принимает и предполагает, что работает с кодовой точкой, которая является скалярным значением, работает неправильно, если принадлежит суррогатной паре. Например, рассмотрим следующий метод, который вызывает Char.ToUpperInvariant для каждого экземпляра char в string:
Если string содержит строчную букву дезерет (), этот код не преобразует ее в прописную букву (). Код вызывает отдельно для каждой суррогатной кодовой точки и . Однако в самой кодовой точке информации недостаточно, чтобы идентифицировать ее как строчную букву. Таким образом оставляет ее как есть. И таким же образом обрабатывает . В результате буква «𐑉» нижнего регистра в string не преобразуется в букву «𐐡» верхнего регистра.
Вот два варианта правильного преобразования string в верхний регистр:
-
Вызовите String.ToUpperInvariant для входного экземпляра string, а не в итерации -by-. Метод имеет доступ к обеим частям каждой суррогатной пары, поэтому он может правильно обрабатывать все кодовые точки Юникода.
-
Выполните итерацию скалярных значений Юникода в качестве экземпляров , а не экземпляров , как показано в следующем примере. Так как экземпляр является допустимым скалярным значением Юникода, его можно передать в API-интерфейсы, которые должны работать со скалярным значением. Например, вызвав Rune.ToUpperInvariant, как показано в следующем примере, вы получите правильные результаты:
Другие API-интерфейсы Rune
Тип предоставляет аналоги многих API-интерфейсов . Например, приведенные ниже методы отражают статические API-интерфейсы для типа :
- Rune.IsLetter
- Rune.IsWhiteSpace
- Rune.IsLetterOrDigit
- Rune.GetUnicodeCategory
Чтобы получить необработанное скалярное значение из экземпляра , используйте свойство Rune.Value.
Чтобы преобразовать экземпляр обратно в последовательность типов , используйте метод Rune.ToString или Rune.EncodeToUtf16.
Так как любое скалярное значение Юникода может быть представлено одним экземпляром или суррогатной парой, любой экземпляр может быть представлен не более чем двумя экземплярами . Используйте Rune.Utf16SequenceLength, чтобы узнать количество экземпляров , требуемых для представления экземпляра .
Дополнительные сведения о типе .NET см. в справочнике по API для .