Всем привет! В этой первой части серии Ого, это фантастика! мы поговорим о UTF-8 и его загадочных, умопомрачительных способах.

Но давайте рассмотрим это с самого начала.

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

Я хочу сказать, что я стар. И как пожилой человек я вырос на ASCII.

А ASCII прост:

Один байт на символ. Один символ на байт. Красивый.

Затем я сделал перерыв в компьютерах на несколько лет, а когда вернулся, там была вся эта штука с UTF-8.

Итак, я узнал о рунах и всем остальном (это Голанг, если вам интересно), и какое-то время, по крайней мере, функционально, все было в порядке.

Но знаете, я любопытный человек, и в конце концов я бы не стал любопытным.

Что привело меня к…

Я имею в виду, конечно, не так ли? UTF-8 требует более одного символа на байт, иначе как бы он закодировал миллиард разных символов?

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

Отлично.

Но как это работает?

1. Соединяются ли байты акцента с байтами ASCII для формирования новых символов?

2. Есть ли байты-разделители между байтами символов, что означает, что все, что находится между разделителями, сливается в кучу?

3. Это какая-то черная магия?

Давайте посмотрим:

Нет и нет. Черт возьми.

(А насчет №3 мои потусторонние консультанты сказали, что это не так.)

Так как?

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

Имея в виду:

- Если ваш байт начинается с нуля, это обычный символ ASCII.

- Если ваш байт начинается со 110, вы получили двухбайтовый символ.

- Если ваш байт начинается с 1110, вы получили трехбайтовый символ.

- 11110 означает четыре.

- И все 10 * байтов, так сказать, «коннекторы».

Чтобы узнать, работает ли это:

Давайте поразмышляем над этим, прежде чем я покажу вам результат. У нас есть четыре символа, и их кодовые точки: U + 0061, U + 00E3, U + 9999 и U + 1F914. Они должны быть длиной один, два, три и четыре байта соответственно.

То есть у нас должны быть:

- Для нашего первого символа: один байт, начинающийся с нуля.

- Второй символ: один байт начинается с 110, за ним следует другой, начинающийся с 10.

- Третий символ: первый байт начинается с 1110, следующие два начинаются с 10.

- Четвертый символ: первый байт начинается с 11110, следующие три начинаются с 10.

Давайте посмотрим:

Немного перетасовал для наглядности:

1. 01100001

2. 11000011 10100011

3. 11101001 10100110 10011001

4. 11110000 10011111 10100100 10010100

Потрясающие!

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

- 11000011 10100011 → 00011 100011

- 11101001 10100110 10011001 → 1001 100110 011001

- 11110000 10011111 10100100 10010100 → 000 011111 100100 010100

Что мы можем использовать для:

Результат здесь: e3 9999 1f914. Другими словами:

- 00011100011 → 0xE3 (ã)

- 1001100110011001 → 0x9999 (香)

- 000011111100100010100 → 0x1F914 (🤔)

Итак, поехали.

Сейчас в мире все хорошо.

Мы знаем, как UTF-8 творит чудеса.

Or do we?

Вы когда-нибудь задумывались, что происходит, когда четырехбайтовый символ…

… Встречает специальный четырехбайтовый символ, а затем два из них…

… Заниматься озорством на двадцать семь байт и…

… Они попадают в большую счастливую семью длиной в двадцать пять байтов?

Ты сделаешь? Потрясающие! Следите за следующей публикацией!

Спасибо за чтение! Если вам понравилась эта статья, поделитесь ею и обязательно подпишитесь на dEffective Go!