Из образовательного интереса. <br/> Как создать и установить в Windows и Linux расширенную ASCII‑кодировку или любую другую кодировку: в каком виде кодировка хранится и подключается в системе, на каком языке пишутся её реализации? <br/> С чего лучше начать изучение и какие книги или статьи по этой теме порекомендуете?
Коротко — ответ в двух частях: (1) что такое кодировка и как её проектировать/реализовывать; (2) как её «подключать» в приложениях/системе (Windows/Linux) и с чего начать изучение.
1) Что такое «своя кодировка» (концепция) и как её проектировать
- Кодировка — это правило отображения между набором символов (обычно Unicode code points или собственным набором графем) и последовательностями кодовых единиц (обычно байтов). Нужно определить:
- единицу кодирования (обычно байт = 8 бит; могут быть 16‑бит слова и т.д.);
- однобайтная или многобайтная (фиксированная/переменная длина) схема;
- алфавит (какие символы кодируем): например, subset Unicode, или уникальная таблица символов;
- однозначность/самодостаточность (чтобы декодер мог однозначно распознать границы кодовых единиц);
- поведение при ошибках (replacement, exception), BOM, порядок байтов (для 16/32‑бит);
- требование к нормализации/комбинациям (если используете Unicode, решите, будете ли нормализовать);
- дополнительные функции: stateful (ISO‑2022), переключение таблиц и т.д.
- Примеры стратегий:
- single‑byte: таблица длиной 256, где каждому байту сопоставлен символ Unicode. Простой, быстрый.
- multi‑byte с префиксами: UTF‑8 — байты имеют уникальные префиксы, позволяющие синхронизироваться.
- stateful: ISO‑2022 — требуется внутреннее состояние (escape‑последовательности).
- fixed 2‑byte (UTF‑16BE/LE): простая обр. между 16‑бит единицами и Unicode.
- Документируем: таблица/алгоритм преобразования, имя кодировки (IANA‑имя, если планируете публиковать), семантика ошибок.
2) Формат хранения кодировки
- Для простых одно‑байтовых — 256‑элементный массив (byte -> codepoint) и обратная хеш/таблица codepoint -> byte.
- Для многобайтных — конечный автомат/тrie для распознавания префиксов и таблицы переходов; при генерации — алгоритм, преобразующий codepoint → байтовая последовательность.
- Часто кодировку представляют как две таблицы + параметры (endianness, BOM, replacement code) в текстовом или бинарном ресурсном файле; для ICU это набор data‑файлов, для iconv — модуль/библиотека.
3) Как реализовать энкодер/декодер (на уровне приложений)
- Языки/инструменты, где легче писать:
- Python: пишете класс Codec/IncrementalEncoder/Decoder и регистрируете через codecs.register(search_function). Очень удобно для экспериментов.
- Java: реализуете java.nio.charset.Charset + CharsetEncoder/CharsetDecoder и помещаете провайдер (CharsetProvider) в JAR (META‑INF/services).
- .NET: наследовать System.Text.Encoding и/или реализовать EncodingProvider и зарегистрировать через Encoding.RegisterProvider.
- C/C++: пишете функции/библиотеки; если нужен системный доступ — на C (glibc/gconv, iconv, ICU).
- Rust/Go: аналогично — библиотечный уровень (package).
Пример (очень компактно, идея для Python — однобайтовая таблица):
def encode_one(s, table): # table: dict unicode->byte
return bytes(table.get(ord(ch), 0x3F) for ch in s) # '?'=0x3F replacement
def decode_one(bdata, inv_table): # inv_table: byte->unicode char
return ''.join(inv_table[b] for b in bdata)
4) Как «установить» кодировку в системе (практика)
- Общая рекомендация: не пытайтесь менять NLS/ядро ОС, если цель — учиться или поддерживать приложение. Проще зарегистрировать кодировку в библиотеке, которой пользуется ваше приложение (Python, Java, .NET, ICU, iconv).
- Linux (реально): у glibc есть механизм gconv — плагины (shared libs) в /usr/lib/gconv и запись в /etc/gconv.modules или /etc/gconv.conf. Вы можете написать gconv‑модуль на C, собрать как .so и добавить запись. Для приложений обычно проще:
- добавить модуль для GNU libiconv (если используется);
- либо подключить ICU и добавить конвертер в ICU (потребует работы с ICU data).
- многие программы используют iconv/ICU/Python/Java; добавьте свой кодек туда, где он нужен.
- Windows:
- Windows «на уровне системы» поддерживает фиксированный набор кодовых страниц (NLS). Добавить произвольную кодовую страницу для всей системы — очень сложно и потребует изменения системных NLS‑компонентов и/или подмены DLL — практически нереально для обычного пользователя.
- Практический путь: реализовать кодировку внутри приложения:
- .NET: создать Encoding и зарегистрировать провайдер — каждое приложение может использовать.
- Java: реализовать CharsetProvider и поставлять JAR, который приложение подключает.
- использовать ICU (широко применима на Windows).
- Для интеграции с браузерами/почтовыми агентами — нужно регистрировать имя у IANA (если хотите общепринятое имя).
5) Реализация для системных библиотек (кратко)
- glibc gconv: пишете C‑функции gconv_open/gconv/..., компилируете .so, регистрируете в /etc/gconv.conf. Это низкоуровневая и небезопасная работа (ошибки могут привести к проблемам).
- GNU libiconv: можно включить свои конвертеры при сборке или добавить модули.
- ICU: поставляется с API для добавления «simple converter» — см. документацию ICU Data and Converter creation.
- Windows NLS: Microsoft не предоставляет простой публичный API для добавления новых кодовых страниц; обходной путь — приложение‑уровень.
6) Что почитать и с чего начать (в порядке полезности)
- The Unicode Standard — основной документ (начните с первых глав: concepts, encoding forms).
- Unicode Technical Reports:
- UTR #36 Name? (необязательно), но обязательно UAX #15 (Unicode Normalization), RFC 3629 (UTF‑8), UAX #9 (Bidi) при интересе к направлению.
- "Unicode Explained" — Jukka K. Korpela — хорошее введение.
- "Unicode®: A Primer" и статьи в unicode.org (в FAQ много практических примеров).
- "CJKV Information Processing" — Ken Lunde — если интересует сложные письменности.
- Статьи и блоги:
- Markus Kuhn: "Unicode, character sets, and handling multilingual text" (полезные заметки).
- Michael Kaplan: статьи о Windows и кодировках.
- "What every programmer should know about encodings" — разные заметки и руководства по web.
- Исследуйте исходники:
- Python: каталог Lib/codecs.py, encodings/*.py (наглядно как добавлять кодеки).
- Java: OpenJDK CharsetProvider/Charset реализации.
- glibc gconv примеры и документация.
- ICU исходники и примеры конвертеров.
- RFC и стандарты для старых кодировок: ISO‑8859‑* серии, ISO‑2022, RFCs про MIME charsets.
7) Практические советы и порядок действий для обучения
- Начните с простой одно‑байтовой таблицы: создайте 256‑элементную таблицу, напишите encoder/decoder в Python и протестируйте.
- Добавьте обработку ошибок, тест 100% round‑trip для множества строк.
- Сделайте более сложный пример — преобразователь, похожий на UTF‑8 (prefix bits), реализуйте state machine и тестируйте синхронизацию и recovery.
- Посмотрите, как выглядят реальные реализации (Python/ICU) и попробуйте добавить вашу кодировку в одну из них (например, написать Python‑модуль и зарегистрировать через codecs.register).
- Если цель — системная интеграция под Linux — попробуйте написать gconv‑модуль и установить его на тестовой машине (очень полезно для понимания).
8) Заключение / рекомендации
- Для образовательных целей: реализуйте сначала в высокоуровневом языке (Python/Java), это даст понимание без риска повредить систему.
- Для интеграции с реальными приложениями: экспортируйте свою кодировку как библиотечный модуль (CharsetProvider, EncodingProvider, codecs) или добавьте в ICU/libiconv, а не пытайтесь менять системные NLS в Windows.
- Читайте Unicode Standard и смотрите исходники существующих конвертеров — это лучший путь понять тонкости (нормализация, комбинируемые знаки, ошибка в потоке, BOM, несовместимости).
Если хотите, могу:
- показать конкретный пример реализации однобайтовой кодировки в Python (полный код);
- дать пример Java CharsetProvider skeleton;
- показать пример структуры gconv‑модуля на C для Linux.
Напишите, какой вариант примерa вы хотите — Python/Java/C — и я пришлю рабочий пример и набор тестов.
<blockquote>Образовательный интерес.</blockquote> <br/> Кодировка - сама по себе особо то и не пишется, вот взбрело Вам в голову изобрести свою кодировку - изобретайте. Например решили будет 8 бит на это. Предположим Вы начали 0- пробел, 1- A, 2 - Б .... итд. Ограничено лишь Вашей фантазией, я в качестве примера привел русский, но это может быть к примеру трольий, <br/> пусть так и будет. Опустим момент с клавиатурой. Будем только документы смотреть. Заполнили вы таблицу соответствия отображаемым символам. Теперь у Вас есть кодировка. Назовите, как угодно Вы теперь можете составлять (нужна клавиатура) и смотреть (нужны шрифты) трольи документы в созданной кодировке. Это условно, следующий момент программа просмотра/редактирования. Но и на этом этапе уже можно утверждать что Вы создали кодировку. Как хранятся ваши фалы - как байты; без метаданных о кодировке. <br/> Отображение - только при правильной интерпретации (через iconv или редактор) (на примере Ubuntu) <br/> Шрифты Выбираются по Unicode-кодам после декодирования (Тут тоже момент про глифы, они должны быть, если символ уникален) <br/> Следующий этап - внедрить ее в ОС. <br/> Нужна тролья локаль (тут почитайте погуглите как и что устроено) <br/> Но один из компонентов явно связан, это LC_CTYPE (Какие байты считаются буквами. Как переводить в верхний/нижний регистр. Какие символы — пробелы, цифры и т.д.) и LC_COLLATE (Правила сортировки строк) <br/> Остается iconv. Для него потребуется написать модуль для glibc (модуль преобразования (.so-файл) ) <br/> <br/> Все у Вас теперь своя тролья кодировка. <br/> Это обобщенное описание, не претендующее на истину в первой инстанции, но поможет Вам понять принцип. Ну и отсутствие практической пользы, только как академический интерес. Да и вопрос наверно должен звучать "как подружить экзотическую кодировку с ОС" и для каждой ОС будут свои методы.
Создание кодировки в windows не доступно пользователям, обслуживается полностью компанией майкрософт. <br/> <br/> Есть документация в msdn по использованию, т.е. можно попытаться отреверсить, какие файлы и какие ключи реестра нужно добавить, что бы приложения хотя бы попытались это использовать. <br/> <br/> Само собой, приложения так же должны понимать эту кодировку. <br/> <br/> p.s. можно выбрать для себя range в unicode и пользоваться, для этого есть <a href="https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Private-use_characters" rel="nofollow">https://en.wikipedia.org/wiki/Universal_Character_...</a>
<blockquote>Как создать и использовать свою кодировку знаков?</blockquote> <br/> <br/> 1. Придумайте хорошую кодировку <br/> 2. Убедите вашу целевую группу (весь мир?) её использовать. <br/> <br/> Каков вопрос — таков ответ. <br/> <br/> Могу дать совет по первому пункту. В Юникоде даже т.н. «фиксированные» кодировки фиксированы только по кодепоинтам, но НЕ по символам. Фактически, это затачивает Юникод под UTF-8, потому что нафига кому-то нужен UTF-32, если всё равно нельзя одним смещением в буфере получить адрес i-того символа. Исправьте это, оставив достоинства Юникода, и я серьёзно задумаюсь о переходе на вашу кодировку. <br/> <br/> <blockquote>Как создать и установить в систему Windows/Linux ASCII-расширеную или любую другую кодировку</blockquote> <br/> <br/> Вы исходите из того, что понятие «кодировка» универсальным образом абстрагировано в ОС. А это не так. <br/> <br/> В API винды функции, работающие со строками, дублированы с двумя суффиксами: A и W. Например, <code>SetTextA(hWnd, buffer)</code> будет считать, что buffer содержит текст в одной жёстко заданной кодировке, а <code>SetTextW(hWnd, buffer)</code> будет считать, что buffer содержит текст в другой жёстко заданной кодировке. Таким образом, используемые СИСТЕМОЙ кодировки ограничены двумя заданными. Чтобы добавить свою кодировку, винда должна была быть устроена так: <br/> <br/> <pre><code class="cpp">HENCODING hEncoding = CreateEncoding(…тут колбэк или описание кодировки на декларативном языке…); auto buffer = …тут текст в вашей кодировке…; SetText(hWnd, hEncoding, buffer);</code></pre> <br/> <br/> Но это астронавтика. Поэтому добавить кодировки в СИСТЕМУ уже нельзя, а можно только на уровне приложений. <br/> <br/> Если нужно что-то типа схем трансляции NLS, которые в винде представлены в реестре, лучше написать конкретику.
<blockquote>Вопрос в том, как создать с ноля кодировку и установить её в систему, чтобы при создании текстового файла и при выборе кодировки, в которой этот файл будет представляться, в перечне присутствовала эта кодировка и отображала в тексте её знаки.</blockquote> <br/> На самом деле тут четыре задачи: <br/> В целом всё достаточно просто — надо только разобраться как оно всё работает. Третий и четвёртый пункты нужны если у вас свой или нестандартный алфавит. Всё нижеследующее — для винды, как оно делается в линуксе я не знаю, но скорее всего что-то похожее (можно начать <a href="https://linuxvox.com/blog/linux-locale/" rel="nofollow">отсюда</a> ). <br/> <br/> Создать саму кодировку достаточно просто: в общем случае просто нумеруете каждый символ и ваша кодировка готова. В ОС Windows традиционно существует два основных вида кодировок: одно-байтовые и двух-байтовые. Соответственно, до 256 символов в первом случае и до 65535 символов во втором. Системное API поддерживает два вида кодировок: с суффиксом "A" (ANSI) и "W" (wide, Unicode-16). Так же существуют и другие виды кодировок: в половину байта — т.е. 7 бит, размером в 4 байта — юникод-32, есть даже гибридные, в которых символы могут занимать как один байт, так и больше. Это сегодняшний международный стандарт: utf-8. <br/> <br/> Теперь вам нужно сообщить системе, что есть такая кодировка. Деталей формата не знаю и как оно в целом работает тоже — просто быстро поглядел документацию. Так что тут вам предстоит самостоятельно выяснить все детали. Советую начать с <a href="https://learn.microsoft.com/en-us/windows/win32/intl/nls-terminology" rel="nofollow">официальной документации</a> . Файлы кодировок хранятся по следующему пути: <code>%windir%\System32\c_XXXX.nls</code> . в формате nls и в виде списка в реестре по пути <code>HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage</code> . Возможно что-то ещё потребуется. Вот тут вроде как есть редактор для кодовых страниц со всеми инструкциями: h <a href="http://www.barrcentral.com/Help/Beps/BEPS.htm#Using_the_Code_Page_Editor.htm" rel="nofollow">ttp://www.barrcentral.com/Help/Beps</a> — но судя по всему редактор там идёт вместе со всем пакетом данного софта, т.к. на странице загрузок его нет отдельно, только <a href="http://www.barrcentral.com/Products/beps/default.aspx" rel="nofollow">весь пакет</a> . <br/> Для стандартного алфавита этого уже достаточно и должно всё работать. В теории, конечно же. Как будет на практике — тут надо выяснять, что надо сделать ещё и где настроить. Например, для консольных и оконных приложений оно может работать по-разному. <br/> <br/> Для отображения символов какого-то нового алфавита вам потребуется шрифт. В целом шрифт создать очень просто: редакторов шрифтов полно. Шрифт по сути это список из двух пар: число и картинка символа. Есть два основных вид шрифтов: пиксельные и векторные. Пиксельные — это обычные картинки из стандартных пикселей для каждого размера символов. А вот векторные шрифты универсальны для всех размером: вместо пикселей математические функции, которые описывают линии символов. <br/> <br/> И последний шаг для вашего алфавита: локализация/раскладка клавиатуры. Тут всё просто: для этого используется <a href="https://www.microsoft.com/en-us/download/details.aspx?id=102134" rel="nofollow">Microsoft Keyboard Layout Creator</a> . Инструкций в сети по нему тоже много — даже на хабре есть подробная инструкция с примерами. В целом там всё достаточно просто, но как в нём работать с новым алфавитом и кодировкой точно не скажу, т.к. я делал раскладку только для русского/английского и стандартных кодировок. <br/> <br/> В реальном мире всё несколько сложнее и для настоящей работы со своей кодировкой этого всего этого будет, скорее всего, недостаточно, т.к. нужна ещё поддержка со стороны ПО, которое будет использовать данную кодировку. Особенно, если она нестандартная или надо сделать что-то большее, чем просто напечатать символ на экране. Так что если какое-то приложение рассчитано на работу со стандартными кодировками, то при попытке использовать вашу кодировку в лучшем случае можно будет увидеть просто кракозябры, а в худшем — приложение банально не будет работать или падать с ошибкой. <br/> <br/>