Серверная (www.it-simple.ru)

Работаем с блокнотом


Очередной фокус с микрософтовским продуктом.
Сразу оговорюсь: точно работает под Windows XP, в висте и семёрке не проверял.

Откроем блокнот ( Windows+R, notepad, Enter ) и напишем:

яюлевсегдапишубезпробелов!
потому что она мне так пишет!!!

и сохраним результат на рабочий стол под именем test.txt. Закрываем блокнот.

Открываем файл заново и впечатляемся.
Красиво, правда?


Всё дело в волшебном сочетании символов «яю» в начале файла. Создайте новый текстовый документ, введите (или скопируйте) туда любой текст, поставьте первыми символами «яю» - и всё, блокнот его больше не прочитает. Вернее, блокнот-то прочитает, вы не прочитаете.

Символы «яю» в стандартной windows-кодировке (cp-1251) представляют собой сочетание байт FFFE (в шестнадцатиричном представлении). Это сочетание указывает блокноту (и ряду других текстовых редакторов), что документ надо читать в кодировке юникода.

Помимо сочетания «яю» работает ещё «юя» и некоторые комбинации этих символов с другими буквами, цифрами и символом переноса строки (см. комментарии).

И вот это уже по-настоящему смешно, потому что:

  1. В тексте UTF-8 принципиально не может быть байтов со значениями 254 (0xFE) и 255 (0xFF). Поскольку в Юникоде не определены символы с кодами выше 221, то в UTF-8 оказываются неиспользуемыми также значения байтов от 248 до 253 (0xF8—0xFD). Если запрещены искусственно удлинённые (за счёт добавления ведущих нулей) последовательности UTF-8, то не используются также байтовые значения 192 и 193 (0xC0 и 0xC1).

    http://ru.wikipedia.org/wiki/UTF-8 (http://ru.wikipedia.org/wiki/UTF-8)
  2. Выбрать кодировку для сохранения в блокноте нельзя. Новый документ будет сохранён в кодировке cp-1251.
  3. При сохранении нового файла блокнот не проверяет текст на наличие "инструкций" — "опасных" сочетаний символов.
  4. При чтении нашего файла блокнот тупо следует инструкциям и пытается вывести текст в юникоде.
  5. Переключения кодировок в блокноте нет.

Вдобавок,

Многие программы Windows (включая Блокнот) добавляют байты 0xEF, 0xBB, 0xBF в начале любого документа, сохраняемого как UTF-8. Это метка порядка байтов Юникода (англ. Byte Order Mark, BOM), также её часто называют сигнатурой (соответственно, UTF-8 и UTF-8 with Signature). По наличию сигнатуры программы могут автоматически определить, является ли файл закодированным в UTF-8, однако файлы с такой сигнатурой могут некорректно обрабатываться старыми программами, в частности xml-анализаторами. Такие редакторы, как Notepad++, Notepad2 и Kate, позволяют явно указывать, следует ли добавлять сигнатуру при сохранении UTF-файлов.

(http://ru.wikipedia.org/wiki/UTF-8 (http://ru.wikipedia.org/wiki/UTF-8)), но винда вместо байт EFBBBF использует именно FFFE. Это легко проверить — например, экспортировав любую ветку реестра (по умолчанию reg-файлы сохраняются в кодировке юникода) и открыв получившийся файл с помощью шестнадцатиричного редактора.

Заставим баги микрософта работать на себя: такое поведение блокнота можно использовать в качестве шифрования документов, чтобы чайники их не прочитали.

А лучше вместо блокнота сразу поставить или Notepad++ (http://notepad-plus.sourceforge.net/ru/site.htm), или FAR Manager (http://www.farmanager.com/), или оба сразу.