Задача

Инфинитивы (неопределённые формы) некоторых русских глаголов были записаны при помощи кодировки Windows-1251, а затем по ошибке прочитаны в кодировке Windows-1252.

1. ìûòü 5. êëàñòü 9. òå÷ü
2. âåñòè 6. áðèòü 10. ïîëçòè
3. íåñòè 7. âåçòè 11. ïå÷ü
4. ñòðè÷ü 8. êðûòü 12. êóñàòü

Задание 1. Восстановите исходный вид этих инфинитивов.

Задание 2. Попробуйте выполнить то же задание для инфинитивов øèòü и æèòü.

Задание 3. Запишите тем же способом, который представлен в условии задачи: съем, фейерверк, ищи, ёлка. Если в каком-то случае вы не можете этого сделать, объясните, почему.


Подсказка 1

Подумайте, чем могут заканчиваться неопределённые формы глаголов.


Подсказка 2

Попробуйте выписывать найденные соответствия в алфавитном порядке.


Решение

В задаче представлено несколько инфинитивов русских глаголов, которые в результате ошибки вместо букв русского алфавита стали состоять из других символов; в основном это латинские буквы с разными диакритическими знаками, но встречается и знак деления ÷ (в дальнейшем, чтобы не путаться, мы будем называть эти латинские буквы просто символами, а буквами — русские буквы). Учитывая, что 4–6 букв — довольно обычная длина русских инфинитивов, наиболее естественно будет предположить, что каждый символ заменяет ровно одну букву.

Вспомним, какими двухбуквенными сочетаниями могут кончаться инфинитивы русских глаголов (их морфемный статус нам сейчас неважен). Это -ть (подавляющее большинство глаголов, например бегать), -ти (идти) и -чь (стеречь), а также -ся (драться) и -сь (нестись) у возвратных глаголов. В инфинитивах, представленных в задаче, варианта всего три: òü, òè и ÷ü. Из общих соображений понято, что возвратных глаголов в задаче нет, но лучше будет доказать это строго.

Мягкий знак — единственная буква, которой могут кончаться инфинитивы и перед которой в инфинитивах может быть несколько разных букв: т, ч и с. Значит, символ ü, перед которым встречаются ò и ÷, заменяет именно мягкий знак. Если среди данных глаголов есть возвратные, то в их числе должны быть глаголы на -сь (если бы это были только глаголы на -ся, обе буквы их двухбуквенного окончания были бы уникальны, но у òü и òè совпадает предпоследняя буква, а у òü и ÷ü — последняя). Эти глаголы на -сь в представленном виде заканчивались бы либо на òü, либо на ÷ü, — но среди инфинитивов с обоими окончаниями есть такие, которые состоят из четырёх букв (ìûòü, òå÷ü), а возвратных глаголов с четырёхбуквенным инфинитивом, очевидно, не существует, ведь только суффикс инфинитива вместе с возвратным суффиксом занимает как раз четыре буквы (-ться или -тись). Значит, возвратных глаголов в задаче действительно нет, а òü, òè и ÷ü заменяют соответственно -ть, -ти и -чь.

Теперь мы знаем соответствия для четырёх букв и можем приступать к расшифровке основ глаголов. Обратим внимание на слово òå÷ü: в нём нам неизвестна только вторая буква, то есть оно имеет вид т_чь. Очевидно, что вторая буква должна означать гласный; несложным перебором можно убедиться, что единственный подходящий глагол — течь, то есть å заменяет букву е.

Далее можно рассмотреть группу инфинитивов вида _е_ти: âåñòè, íåñòè и âåçòè. Заметим, что в большинстве инфинитивов на -ти этому суффиксу предшествуют буквы с или з (упомянутое выше идти — одно из немногих исключений): расти, грести, мести, ползти... Среди них есть два инфинитива, отличающиеся только этой буквой и неразличимые на слух: вести и везти; скорее всего, âåñòè и âåçòè — это именно они. При этом других глаголов вида _езти не существует; значит, íåñòè — это какой-то глагол на -ести (типа мести или нести), символ ñ заменяет с, ç — з, а â — в.

В инфинитиве ñòðè÷ü нам теперь неизвестна только третья буква; оставшаяся его часть выглядит как ст_ичь. Несложно догадаться, что это слово стричь (в крайнем случае можно перебрать все буквы, соответствий которых мы пока не знаем). Таким же образом, догадавшись или применив перебор, можно выяснить, что áðèòü (_рить) — это брить.

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

б в е з и р с т ч ь
á â å ç è ð ñ ò ÷ ü

Мы видим, что латинские буквы с диакритическими знаками тоже расположились по алфавиту: сначала разные «версии» буквы a, затем c, e, i, n, o и, наконец, u. Хотя из этой закономерности несколько выбивается буква ð, вообще-то происходящая от d, вряд ли это случайность; при дальнейшей расшифровке мы можем опираться на наше наблюдение.

Теперь обратимся к инфинитиву êóñàòü (__с_ть). Очевидно, четвёртая буква в нём обозначает гласный; скорее всего, это а, так как её заменяет символ à, то есть она находится в начале алфавита. Вторая буква, видимо, располагается в алфавите между т и ь; это наверняка у, поскольку все остальные буквы из этого диапазона сложно представить себе в такой позиции. Получается, что этот инфинитив — кусать, то есть ê заменяет букву к.

Оставшиеся инфинитивы уже несложно расшифровывать в таком порядке, чтобы в каждом из них была неизвестна только одна буква: êëàñòü (к_асть) — это класть (конечно, не красть, ведь мы знаем, что р заменяется другим символом; кстати, заметим, что соседние в алфавите буквы к и л обе заменяются латинской e с разными надстрочными знаками), êðûòü (кр_ть) — крыть, ïå÷ü (_ечь) — печь, ïîëçòè (п_лзти) — ползти.

Итак, остались нерасшифрованными только два символа в двух инфинитивах: ìûòü (_ыть) и íåñòè (_ести). Оказывается, что оба символа могут заменять как м, так и н, ведь существуют глаголы мыть, ныть, мести и нести. Чтобы разобраться, вновь прибегнем к соображениям об алфавитном порядке и составим таблицу.

а б в е з и к л м н о п р с т у ч ы ь
à á â å ç è ê ë ì/í ì/í î ï ð ñ ò ó ÷ û ü

Интересующие нас символы представляют собой латинскую букву i с разными диакритическими знаками:  ̀ (гравис) и   ́ (акут). Взглянув на таблицу, мы видим, что другие буквы с грависом и акутом заменяют соседние в алфавите кириллические буквы, причём первую из них заменяет буква с грависом, а вторую — буква с акутом: à заменяет а, á — б; ò заменяет т, ó — у. Значит, ì заменяет м, а í — н, то есть в задаче представлены инфинитивы мыть и нести, а не ныть и мести.

Выпишем ещё раз все расшифрованные нами инфинитивы:

1. мыть 5. класть 9. течь
2. вести 6. брить 10. ползти
3. нести 7. везти 11. печь
4. стричь 8. крыть 12. кусать

Мы выполнили задание 1 и можем приступать к заданию 2. Здесь даны ещё два инфинитива вида _ить, первые буквы которых нам неизвестны. Среди тех немногочисленных букв, соответствий которых мы не узнали из задания 1, в такой позиции могут оказаться как раз две: ж и ш. Чтобы выяснить, какая из записей соответствует глаголу жить, а какая — глаголу шить, нам снова придётся обратиться к алфавиту: æ — это лигатура букв a и e, то есть она скорее окажется ближе к началу алфавита, а ø — перечёркнутая буква o, которая должна быть ближе к концу. Значит, øèòü — неправильно прочтённый инфинитив шить, а æèòü — жить.

Перейдём к заданию 3. В словах, данных в нём, есть несколько букв, соответствий которых мы так и не встретили: ъ, ф, й, щ и ё. Конечно, здесь нам снова поможет алфавитный порядок. Проще всего разобраться с й: как и в случае с м и н, если букву и заменяет буква è с грависом, то следующую за ней по алфавиту букву й должна заменять буква é с акутом.

Для остальных случаев правило, которое мы сформулировали, расшифровывая ì и í, нужно обобщить. Мы можем заметить, что за парами букв с грависом и акутом всегда следует третья буква с надстрочным знаком ̂  (циркумфлекс): а, б и в соответствуют à, á и â; и, й и к — è, é и ê; м, н и о — ì, í и î. Скорее всего, это обобщённое правило распространяется и на другие латинские гласные буквы. Значит, буква ф, поскольку она следует в алфавите за у, должна заменяться на ô, а щ и ъ, так как они находятся непосредственно перед ы, — на ù и ú соответственно. В правильности последнего утверждения можно убедиться дополнительно: ещё одна закономерность в распределении диакритических знаков, которую мы могли заметить, состоит в том, что первой по алфавиту из всех форм той или иной латинской гласной буквы всегда оказывается буква с грависом; здесь это ù, соответствующая щ, а из задания 2 мы знаем, что букве ш, которая предшествует щ в алфавите, соответствует ø — форма другой, более близкой к началу латинского алфавита буквы.

Что касается буквы ё, соответствующий ей символ мог бы оказаться где-то между å и æ (соответствий е и ж), но мы не можем узнать, какой именно диакритический знак можно было бы присоединить к букве a, тем более что нам не попадалось ни других символов с надстрочным кружком, ни других лигатур. Значит, записать таким образом слово ёлка, опираясь на данные задачи, мы не можем. Именно на этот случай в задании есть пояснение о том, что в каком-то случае нам, возможно, не удастся его выполнить.

Полностью запишем нужным образом те слова из задания 3, с которыми у нас получится это сделать:

1. съемñúåì
2. фейерверкôåéåðâåðê
3. ищиèùè

Задача решена!


Послесловие

Ýòî ïîñëåñëîâèå ìîãëî áû íà÷èíàòüñÿ òàê. хКХ БНР РЮЙ.
Это послесловие могло бы начинаться так. Или вот так.

Но, к счастью, оно так не начинается: за семьдесят лет развития компьютеров человечество научилось хранить и отображать символы почти всех естественных языков, которые используются и когда-либо использовались на Земле. Правда, путь к этому достижению был тернистым.

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

Мы знаем, что в русском алфавите 33 буквы. Умножим это число на два, поскольку буквы бывают строчные и прописные, не забудем пробел, 10 цифр и пару десятков знаков препинания — в итоге получится около 100. Если записывать всё это двоичными последовательностями одинаковой длины, понадобится 7 двоичных цифр (бит) на символ: 0000000, 0000001, 0000010, 0000011, 0000100, ..., 1111110, 1111111 — всего таких последовательностей насчитывается 27 = 128, нам как раз хватит. Шестью битами не обойтись: они дадут только 26 = 64 комбинации. Другое дело, что если каждый начнёт придумывать коды для своего компьютера самостоятельно, то получится разнобой. Кто-то сделает так:

А = 0000000, Б = 0000001, В = 0000010, ...,

кто-то так:

а = 0000000, б = 0000001, в = 0000010, ...,

а кто-то так:

0 = 0000000, 1 = 0000001, 2 = 0000010, ....

Необходимость стандартизации привела к тому, что в 1963 году возникла единая кодировка для английского языка — ASCII (American Standard Code for Information Interchange). В ней первые 32 места и последнее место занимают различные служебные символы (начало текста, перевод строки, звуковой сигнал, отмена передачи и т. п.), а оставшиеся 95 символов отведены под печатаемые символы — это примерно и есть та сотня символов, которую мы описали выше для русского языка, только для латиницы:

!"#$%&\'()*+,-./0123456789:;<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
`abcdefghijklmnopqrstuvwxyz{|}~

В этой кодировке ! = 01000012 = 3310 (числа 2 и 10 снизу означают «в двоичной системе» и «в десятичной системе» соответственно), A = 10000012 = 6510, a = 11000012 = 9710 и т. д. Кстати, между заглавными и строчными латинскими буквами неслучайно вставлены именно 6 знаков препинания: при том, что длина английского (латинского) алфавита составляет 26 символов, — это даёт разницу между парными буквами ровно на 32 — то есть меняется с 0 на 1 только шестая справа цифра двоичной записи (сравните выше коды для A и a).

Но на каких языках можно писать с помощью этих символов? Их не так-то много: английский (не будем брать в расчёт редкие слова вроде naïve), нидерландский, баскский, ток-писин... А по-немецки уже не получится: например, последние слова Фауста, которые в переводе Бориса Пастернака гласят «И это торжество предвосхищая, / Я высший миг сейчас переживаю», у Гёте выглядят так:

Im Vorgefühl von solchem hohen Glück
Genieß' ich jetzt den höchsten Augenblick.

В ASCII нет букв ü, ß и ö — можно, конечно, обойтись и без них и написать Vorgefuehl вместо Vorgefühl, Glueck вместо Glück, Geniess' вместо Genieß' и hoechsten вместо höchsten, но всё-таки хотелось бы этого избежать. I po-russki mozhno pri neobhodimosti pisat' v ASCII, no eto tozhe ne luchshij variant.

Поэтому появляются 8-битные кодировки, в которых на один символ приходится не 7 двоичных цифр, а 8; это небольшое увеличение сразу расширяет пространство возможностей вдвое — до 28 = 256 символов. Большинство 8-битных кодировок совпадают с ASCII в первых 128 символах, а оставшиеся символы — это и есть та прибавка, которая позволяет записывать другие языки.

Например, кодировка Windows-1252 (или CP-1252) — это ASCII вот с таким добавлением:

€‚ƒ"...†‡ˆ‰Š<ŒŽ"’""•–—˜TMš>œžŸ
 ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿
ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞß
àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ

Читатель может поинтересоваться, почему среди латинских букв появляется знак деления (÷), который обращает на себя внимание и в задаче, и знак умножения (×), соответствующий ему, как прописная буква строчной. При разработке кодировки ISO/IEC 8859-1, на которой основана Windows-1252, предполагалось, что на этих местах расположится лигатура Œœ, которая используется во французском языке. Однако именно французский делегат по какой-то причине настаивал на том, что эту лигатуру можно заменить на диграф oe и включать её в кодовую страницу не нужно, поэтому освободившиеся места были заполнены математическими символами. В кодировке Windows-1252 лигатура Œœ, как можно заметить, всё-таки появилась вместе с ещё несколькими латинскими буквами. Дело в том, что в ISO/IEC 8859-1 кодовые позиции 128–159 (первая строка в перечне выше) не были определены, и сначала заполнялись управляющими (служебными) символами.

Поскольку прибавился лишний бит, символы ASCII теперь записываются с нулём в начале (A = 010000012, а не 10000012), а коды новых символов начинаются с 1: например, ü = 111111002 = 25210. В этой кодировке появляются:

  • финансовые символы: знаки британского фунта £, японской иены ¥, цента ¢, а впоследствии и евро €;
  • изысканные знаки препинания: многоточие как единый символ ... (а не три точки), два тире разной длины – и —, апострофы и кавычки разного рисунка (внимательный читатель наверняка заметил, что в цитате из Гёте лучше бы смотрелось Genieß’, а не Genieß', но правильного апострофа в ASCII не было);
  • дроби;

а главное,

  • буквы, которые позволяют писать на распространённых западноевропейских языках.

С помощью кодировки Windows-1252 могут записываться:

  • многие германские языки: немецкий, шведский, норвежский, датский, исландский, фарёрский;
  • многие романские языки: французский, итальянский, испанский, португальский;
  • некоторые финно-угорские языки: финский, эстонский.

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

Славянские языки с кириллицей — русский, украинский, сербский, белорусский, болгарский, македонский — пользуются кодировкой Windows-1251 (CP-1251):

ЂЃ‚ѓ"...†‡€‰Љ<ЊЌЋЏђ"’""•–—TMљ>њќћџ
ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕї
АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
абвгдежзийклмнопрстуфхцчшщъыьэюя

Мы говорили, что ü — это символ с кодом 252 в Windows-1252. А в Windows-1251 символ с кодом 252 — это ь. Именно отсюда и берутся проблемы с кодировками, представленные в задаче: в разных кодировках разным символам соответствует один и тот же номер, и если вам дана последовательность символов без явного указания кодировки с кодами

234 — 240 — 251 — 242 — 252
(в двоичной записи:
11101010 — 11110000 — 11111011 — 11110010 — 11111100),

то её можно прочитать:

  • ęđűňü в кодировке Windows-1250 (для славянских восточноевропейских языков с латиницей: польского, чешского, словенского, хорватского, — а также румынского и венгерского);
  • крыть в кодировке Windows-1251;
  • êðûòü в кодировке Windows-1252;
  • κπϋςό в кодировке Windows-1253 (для греческого);
  • êğûòü в кодировке Windows-1254 (та же Windows-1252, но с заменой нескольких особых исландских букв на турецкие);
  • źšūņü в кодировке Windows-1257 (для латышского, литовского и польского);

и так далее.

Вот полная таблица соответствий символов девяти 8-битных кодировок из семейства Windows-125x:

Таблица Windows-кодировок (посмотреть/скрыть)

Десятич-
ный код
Двоич-
ный код
Windows-...
1250 1251 1252 1253 1254 1255 1256 1257 1258
128 10000000 Ђ
129 10000001 Ѓ پ
130 10000010
131 10000011 ѓ ƒ ƒ ƒ ƒ ƒ ƒ
132 10000100
133 10000101
134 10000110
135 10000111
136 10001000 ˆ ˆ ˆ ˆ ˆ
137 10001001
138 10001010 Š Љ Š Š ٹ
139 10001011
140 10001100 Ś Њ Œ Œ Œ Œ
141 10001101 Ť Ќ چ ¨
142 10001110 Ž Ћ Ž ژ ˇ
143 10001111 Ź Џ ڈ ¸
144 10010000 ђ گ
145 10010001
146 10010010
147 10010011
148 10010100
149 10010101
150 10010110
151 10010111
152 10011000 ˜ ˜ ˜ ک ˜
153 10011001
154 10011010 š љ š š ڑ
155 10011011
156 10011100 ś њ œ œ œ œ
157 10011101 ť ќ ¯
158 10011110 ž ћ ž ˛
159 10011111 ź џ Ÿ Ÿ ں Ÿ
160 10100000
161 10100001 ˇ Ў ¡ ΅ ¡ ¡ ، ¡
162 10100010 ˘ ў ¢ Ά ¢ ¢ ¢ ¢ ¢
163 10100011 Ł Ј £ £ £ £ £ £ £
164 10100100 ¤ ¤ ¤ ¤ ¤ ¤ ¤ ¤
165 10100101 Ą Ґ ¥ ¥ ¥ ¥ ¥ ¥
166 10100110 ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦
167 10100111 § § § § § § § § §
168 10101000 ¨ Ё ¨ ¨ ¨ ¨ ¨ Ø ¨
169 10101001 © © © © © © © © ©
170 10101010 Ş Є ª ª × ھ Ŗ ª
171 10101011 « « « « « « « « «
172 10101100 ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬
173 10101101 ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬
174 10101110 ® ® ® ® ® ® ® ® ®
175 10101111 Ż Ї ¯ ¯ ¯ ¯ Æ ¯
176 10110000 ° ° ° ° ° ° ° ° °
177 10110001 ± ± ± ± ± ± ± ± ±
178 10110010 ˛ І ² ² ² ² ² ² ²
179 10110011 ł і ³ ³ ³ ³ ³ ³ ³
180 10110100 ´ ґ ´ ΄ ´ ´ ´ ´ ´
181 10110101 µ µ µ µ µ µ µ µ µ
182 10110110
183 10110111
184 10111000 ¸ ё ¸ Έ ¸ ¸ ¸ ø ¸
185 10111001 ą ¹ Ή ¹ ¹ ¹ ¹ ¹
186 10111010 ş є º Ί º ÷ ؛ ŗ º
187 10111011 » » » » » » » » »
188 10111100 Ľ ј ¼ Ό ¼ ¼ ¼ ¼ ¼
189 10111101 ˝ Ѕ ½ ½ ½ ½ ½ ½ ½
190 10111110 ľ ѕ ¾ Ύ ¾ ¾ ¾ ¾ ¾
191 10111111 ż ї ¿ Ώ ¿ ¿ ؟ æ ¿
192 11000000 Ŕ А À ΐ À ְ ہ Ą À
193 11000001 Á Б Á Α Á ֱ ء Į Á
194 11000010 Â В Â Β Â ֲ آ Ā Â
195 11000011 Ă Г Ã Γ Ã ֳ أ Ć Ă
196 11000100 Ä Д Ä Δ Ä ִ ؤ Ä Ä
197 11000101 Ĺ Е Å Ε Å ֵ إ Å Å
198 11000110 Ć Ж Æ Ζ Æ ֶ ئ Ę Æ
199 11000111 Ç З Ç Η Ç ַ ا Ē Ç
200 11001000 Č И È Θ È ָ ب Č È
201 11001001 É Й É Ι É ֹ ة É É
202 11001010 Ę К Ê Κ Ê ت Ź Ê
203 11001011 Ë Л Ë Λ Ë ֻ ث Ė Ë
204 11001100 Ě М Ì Μ Ì ּ ج Ģ ̀
205 11001101 Í Н Í Ν Í ֽ ح Ķ Í
206 11001110 Î О Î Ξ Î ־ خ Ī Î
207 11001111 Ď П Ï Ο Ï ֿ د Ļ Ï
208 11010000 Đ Р Ð Π Ğ ׀ ذ Š Đ
209 11010001 Ń С Ñ Ρ Ñ ׁ ر Ń Ñ
210 11010010 Ň Т Ò Ò ׂ ز Ņ ̉
211 11010011 Ó У Ó Σ Ó ׃ س Ó Ó
212 11010100 Ô Ф Ô Τ Ô װ ش Ō Ô
213 11010101 Ő Х Õ Υ Õ ױ ص Õ Ơ
214 11010110 Ö Ц Ö Φ Ö ײ ض Ö Ö
215 11010111 × Ч × Χ × ׳ × × ×
216 11011000 Ř Ш Ø Ψ Ø ״ ط Ų Ø
217 11011001 Ů Щ Ù Ω Ù ظ Ł Ù
218 11011010 Ú Ъ Ú Ϊ Ú ع Ś Ú
219 11011011 Ű Ы Û Ϋ Û غ Ū Û
220 11011100 Ü Ь Ü ά Ü ـ Ü Ü
221 11011101 Ý Э Ý έ İ ف Ż Ư
222 11011110 Ţ Ю Þ ή Ş ق Ž ̃
223 11011111 ß Я ß ί ß ك ß ß
224 11100000 ŕ а à ΰ à א à ą à
225 11100001 á б á α á ב ل į á
226 11100010 â в â β â ג â ā â
227 11100011 ă г ã γ ã ד م ć ă
228 11100100 ä д ä δ ä ה ن ä ä
229 11100101 ĺ е å ε å ו ه å å
230 11100110 ć ж æ ζ æ ז و ę æ
231 11100111 ç з ç η ç ח ç ē ç
232 11101000 č и è θ è ט è č è
233 11101001 é й é ι é י é é é
234 11101010 ę к ê κ ê ך ê ź ê
235 11101011 ë л ë λ ë כ ë ė ë
236 11101100 ě м ì μ ì ל ى ģ ́
237 11101101 í н í ν í ם ي ķ í
238 11101110 î о î ξ î מ î ī î
239 11101111 ď п ï ο ï ן ï ļ ï
240 11110000 đ р ð π ğ נ ً š đ
241 11110001 ń с ñ ρ ñ ס ٌ ń ñ
242 11110010 ň т ò ς ò ע ٍ ņ ̣
243 11110011 ó у ó σ ó ף َ ó ó
244 11110100 ô ф ô τ ô פ ô ō ô
245 11110101 ő х õ υ õ ץ ُ õ ơ
246 11110110 ö ц ö φ ö צ ِ ö ö
247 11110111 ÷ ч ÷ χ ÷ ק ÷ ÷ ÷
248 11111000 ř ш ø ψ ø ר ّ ų ø
249 11111001 ů щ ù ω ù ש ù ł ù
250 11111010 ú ъ ú ϊ ú ת ْ ś ú
251 11111011 ű ы û ϋ û û ū û
252 11111100 ü ь ü ό ü ü ü ü
253 11111101 ý э ý ύ ı ż ư
254 11111110 ţ ю þ ώ ş ž
255 11111111 ˙ я ÿ ÿ ے ˙ ÿ
ęđűňü крыть êðûòü κπϋςό êğûòü ךנע êًûٍü źšūņü êđụ̂ü

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

─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥⌡°²·÷
═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©
юабцдефгхийклмнопярстужвьызшэщчъ
ЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ

Если вместо Windows-1251 прочитать последовательность Новый Год в KOI8-R, получится мНБШИ цНД c характерной перестановкой строчных и заглавных.

8-битные кодировки плохи ещё и тем, что подходят только для языков с буквенными письменностями, в которых не так уж много символов — каждая буква обозначает один знак. Даже для языков со слоговыми письменностями это неудобно: например, в амхарском языке (официальный язык Эфиопии) около 300 знаков, то есть больше, чем 28 = 256. А уж китайские иероглифы в 8-битную кодировку и вовсе не уместятся.

Как же с этим справиться? Надо, чтобы у каждого символа был уникальный код: если уж сказано «символ с кодом 240», то это всегда ð, а не đ, р, π, ğ или š. Но тогда кодов должно быть намного больше, чем 256. Именно так устроена система Unicode (Юникод), разработанная в 1991 году. В ней первые 256 символов в основном повторяют кодировку Windows-1252, дальше идут символы расширенной латиницы для всех упомянутых в этом послесловии языков с латинской письменностью и не только, знаки фонетической транскрипции, над- и подстрочные знаки и символы других алфавитов. Например, алфавит новогреческого языка располагается в диапазоне от 902-го до 974-го символа, 32 буквы русского алфавита в заглавном и строчном вариантах (без Ё и ё), занимают места с 1040-го по 1101-е, и так далее. Теперь уже точно не ошибёшься при отображении символов, потому что все коды уникальны:

  • ð — 240;
  • đ — 273;
  • р — 1088;
  • π — 960;
  • ğ — 287;
  • š — 353.

Почему же люди придумали Юникод не сразу, а придумав, не сразу начали им пользоваться? Ведь мы сказали, что этот стандарт возник в 1991 году, но ещё в нулевые годы XXI века мы часто сталкивались с íåïðàâèëüíûìè êîäèðîâêàìè — ой, то есть с МЕОПЮБХКЭМШЛХ ЙНДХПНБЙЮЛХ — ой, то есть с неправильными кодировками. Ведь кажется, что такой стандарт — это тривиальная идея, как только начинаешь задумываться о многоязычии.

Но есть ещё одна проблема: память компьютера надо использовать экономно. Если записать кириллическую букву р как 108810 = 100010000002, это 13 бит. А если учесть, что в компьютерах принято хранить информацию блоками по 8 бит (байтами), то получаем 2 байта на символ. На одной 3,5-дюймовой дискете помещается 1,44 мегабайта информации, а точнее говоря, 1 457 664 байта. А, например, роман Фёдора Достоевского «Преступление и наказание» содержит 1 090 348 символов: если записать всё это в 8-битной кодировке, по 1 байту на символ, одной дискеты как раз хватит (это 1,09 мегабайта), а если на каждый символ будет приходиться по 2 байта, то понадобится 2 дискеты. Поэтому такое неэкономное кодирование никому даже не могло прийти в голову.

Помогли две вещи. Во-первых, выросли доступные объёмы памяти: сейчас нам уже более или менее всё равно, весит ли файл 1,09 или 2,18 мегабайта. А во-вторых, Юникод — это не кодировка как таковая, а лишь система нумерации символов: как эти номера будут передаваться с помощью нулей и единиц — это отдельный вопрос. И этот вопрос удалось экономно решить с помощью кодировки UTF-8, которая сейчас используется практически повсеместно и в которой символы ASCII занимают только 1 байт (а ведь в текстах на английском и многих других языках наиболее частотны именно они — базовый латинский алфавит, цифры и знаки препинания), а более редкие символы, так уж и быть, побольше.

Например, латинская буква A в UTF-8 записывается как 01000001 — один байт, так же, как в ASCII. А кодирование для кириллической р выглядит как 11010001 10000000 — два байта. Цветами в этой записи выделены смысловые части. 110 (две единицы, а после них 0 в начале первого байта) показывает, что на символ отводится 2 байта, 10 показывает, что это непервый байт в записи символа, а оставшиеся чёрные цифры как раз и передают код символа: соберите их воедино,  получится 10001000000. Легко посчитать, сколько байт придётся на символ с каким номером:

Байт Формат записи Количество мест для кода символа Максимальный код
1 0....... 7 127
2 110..... 10...... 11 2047
3 1110.... 10...... 10...... 16 65535
4 11110... 10...... 10...... 10...... 21 2097151


Таким образом, 128 самых употребительных символов обозначаются 1 байтом, 1920 менее употребительных символов — 2 байтами, 63488 ещё менее употребительных символов — 3 байтами, а ещё 2031616 символов — 4 байтами. Этого уже с запасом хватает на все письменности мира. Другое дело, что русские буквы всё равно весят по 2 байта, но тут нас спасают большие объёмы современных накопителей.

Конечно, и у Юникода есть свои проблемы. Многие буквы с одинаковыми начертаниями закодированы в нём как символы разных алфавитов. Выше мы обсуждали латинскую A и кириллическую р, а ведь есть ещё русская А (код 1040), греческая Α (код 913) и латинская p (код 112). Коми-зырянское слово вöрöшитны ‘ворошить’ здесь написано неправильно: с латинской ö (код 246) вместо кириллической ӧ (код 1255). А почему бы не считать, что это вообще всё один «мировой» алфавит, и тогда три буквы A можно объединить в одну? Или, наоборот, считать, что русское А и украинское А — это буквы разных алфавитов и должны иметь разные коды? Считать ли ö и ü едиными буквами или надо составлять их из двух символов: o и u и надстрочной пары точек? А русское ы — это единый знак или мягкий знак и палочка? А хорватские буквы (читается как «дж»), lj (читается как «ль»), nj (читается как «нь»)? Под них даже отведены отдельные коды 457, 460, 463, но ими никто не пользуется, предпочитая собирать их из символов d (100) и ž (382) и т. д. А вот словаки, наоборот, активно используют единый символ ď (271).

С кодировкой UTF-8 не слишком удобно работать программистам, поскольку в ней разные символы занимают разное количество байт, — не вполне тривиальный код нужен даже просто для того, чтобы переместить курсор на n символов вправо или влево. А чтобы сложный текст в Юникоде нормально показывался, нужны шрифты, в которых прорисованы все имеющиеся в нём символы. И с этим нередко возникают проблемы, особенно с «экзотическими» языками и с символами, добавленными недавно, вроде знака рубля . Поэтому на всякий случай заранее просим нас извинить, если какие-то буквы в этом послесловии у вас не прочитаются.

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

Задача использовалась во II туре LI Московской Традиционной олимпиады по лингвистике (2021).

Автор задачи и решения — Дмитрий Смирнов.
Автор послесловия — Александр Пиперски.


3
Показать комментарии (3)
Свернуть комментарии (3)

  • another_user  | 27.12.2021 | 15:57 Ответить
    Для тех, кому хочется спойлеров:

    iconv -f utf-8 -t cp1252 <<< ìûòü | iconv -f cp1251 -t utf-8
    Ответить
  • stormwatch  | 15.12.2022 | 22:33 Ответить
    «два тире разной длины — и —»
    — в итоге два тире одинаковой длины :)
    Ответить
    • editor > stormwatch | 16.12.2022 | 00:37 Ответить
      Большое спасибо, исправили.
      Ответить
Написать комментарий
Элементы

© 2005–2025 «Элементы»