Транслит при помощи КОИ-8

9 мая, 00:50 / КОИ-8, Perl, забава, транслит

Кодовая страница КОИ-8 создавалась таким образом, что бы при передаче русского текста по 7-битному каналу связи (то есть, теряя восьмой бит) сохранить его читаемость. Таким образом «Привет, медведь!» превращается в «pRIWET, MEDWEDX!». (Подозреваю, что регистр букв нарочно поменяли местами дабы проще было заметить потерю значащего бита.)

Эту особенность можно применить для создания примитивного транслита — записи русского текста буквами латинского алфавита. Для этого необходимо конвертировать исходный текст в КОИ-8 и отбросить восьмой бит.

	$ echo 'Привет, медведь!' | \
	  iconv -t koi8-r | \
	  perl -pe '$_ = pack "C*", (map {$_ & ~(1<<7)} unpack "C*")'
	pRIWET, MEDWEDX!

Теперь нужно исправить регистр. Несложно заметить, что в КОИ-8 прописная русская буква отличается от строчной лишь шестым битом: «Ы» — 11111001, «ы» — 11011001. Также видно, что все буквы (кроме «ё») имеют установленный седьмой бит. Поэтому проверяем является ли текущий символ буквой и, если да, инвертируем его шестой бит:

	$ echo 'Привет, медведь!' | \
	  iconv -t koi8-r | \
	  perl -pe '$_ = pack "C*", (map {($_ &= ~(1<<7)) & 1<<6 ? $_ ^ 1<<5 : $_} unpack "C*")'
	Priwet, medwedx!

Комментарии

Комментирование временно отключено.

Димка 9 мая, 10:58
Kruto, no nafig tebe perevodit chto-to v translit? Pishesh servis dlya otpravki SMSok?
Максим Вуец 9 мая, 17:59
Димка, just for fun.
Некто 10 мая, 08:03
Занятно.
cybertom 15 мая, 14:28
tr/\x80-\xFF/\x00-\x7F/; # однозначно проще и быстрей!
cybertom 15 мая, 14:32
$ echo 'Привет, медведь!' | \
	  iconv -t koi8-r | \
	  perl -pe '$_ =~ tr/\x80-\xFF/\x00-\x7F/'
Максим Вуец 18 мая, 16:02
cybertom, согласен с тобой. Но тогда теряется смысл всей затеи, ведь твой tr
уже́ не работает на уровне бит. Действительно проще и быстрее отказать от iconv
и сделать лишь один tr с полной таблицей для транслита. Только я хотел
показать не реализацию транслита, а особенность КОИ-8.

А ещё $_ необязательно явно связывать ~= с tr (;
... 19 мая, 09:06
По поводу необязательного связывания известно (это так для читаемости добавлено) конечно проще написать /искомый текст/ чем $_ ~= m/искомый текст/
но от этого суть не меняется.
Смысл моей конструкции в следующем:
если следовать твоему коду, то производительность неизбежно страдает
в следствии индивидуальной посимвольной обработке ("дурь в общем") -
смысла нет в принципе.
Предлагаю использовать табличный метод, в ряде случаев эффект будет даже
более серьезный, за счет совмещения нескольких операций в одну. Подумай!
В качестве операбельного средства можно использовать tr и не только, 
есть и другие вполне отличные варианты.
Как продолжение этого примера мог бы предложить вариант с использованием
подстановки m/(.)/сдвиг($1)/ (пример дан псевдокодом) это опять лучше твоего!
cybertom 19 мая, 09:41
perl -pe 's/(.)/chr(unpack("C",$1)>>1)/ge'
cybertom 19 мая, 09:42
perl -pe '/(.)/chr(unpack("C",$1)>>1)/ge'

или так ;)
cybertom 19 мая, 09:52
предыдущий пост немного неверен (s - нужно обязательно поставить)

perl -pe 's~(.)~chr(ord($1)>>1)~ge'
Максим Вуец 19 мая, 11:40
cybertom, во-первых, это всё просто ради забавы и производительность здесь
абсолютно не играет роли. Во-вторых, твои варианты полностью искажают
первоначальную идею забавы. В-третьих, твой последний код неправильный
в принципе.
AlTi 23 июня, 20:37
Re: Подозреваю, что регистр букв нарочно поменяли местами дабы проще было заметить потерю значащего бита.
Неверно вы подозреваете, до кодировки Koi-8r была Koi-7 (семибитная), у которой последние 32 символа были заняты большими русскими, поэтому так же сделано у Koi-8r (для совместимости). Да и "Кодовая страница КОИ-8 создавалась таким образом, что бы при передаче русского текста по 7-битному каналу связи (то есть, теряя восьмой бит) сохранить его читаемость." от части получается правдой, Koi-8r это наследник Koi-7 которая создавалась так что бы при отсутствии русского шрифта на принтере (или терминале) сообщения на русском всё равно можно было бы прочитать.