Setting the http charset parameter

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, как это можно сделать.

  1. Открываем личный кабинет и переходим в раздел «Файловый менеджер». В нем перемещаемся в директорию с сайтом и находим в корне файл .htaccess – открываем его двойным кликом мыши.
  2. В начало файла необходимо добавить следующий код:
Для UTF-8: AddDefaultCharset UTF-8

Для Windows-1251: AddDefaultCharset WINDOWS-1251

Открываем свой сайт и видим, что ничего не изменилось – так и должно быть. Чтобы внести изменения, очищаем кэш с помощью комбинации клавиш «CTRL+F5» и смотрим результат.

Как видите, сменить кодировку на своем сайте легко. Аналогичным образом мы можем изменить кодировку и на всем сервере – для этого необходимо выполнить следующее (актуально для веб-сервера Apache):

  1. Находим файл httpd.conf, который расположен по адресу: «/usr/local/apache/conf/», и открываем его.
  2. Если нужно поменять 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 для .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector