metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2009-01-01 04:24 pm

О психах и Unicode

Подкинули безумную задачку - есть бинарный файл-словарь. Нужно из него вытащить список слов и вставить в другой словарь.
Ну сел разбираться. Вижу - классика, в начале файла гигантский индекс из записей постоянной структуры с указателями(они на глаз хорошо видны, периодическая структура), после него идут список слов, слова переменной длины. Задача простейшая - определить длину и формат записи индекса, вычитать слова и сохранить в что-то более вменяемое.
Слова в юникоде, и самое главное - в начале файла есть unicode byte order mark(FFFE).
Высчитал длину записи индекса, сдампил его с длиной строки равной длине записи, и смотрю - ну что-то странное откровенно. Вижу что нарастающие указатели, вижу что данные бинарные, но при этом - формат явно уникод, т.е. байт, 0, байт, 0, иногда байт,20, итд.
Ну ладно, сначала думаю, найду где длина слова живет. Взял три слова с начала, посчитал длину, сразу же увидел где она в индексе. Решил почитать пока чисто через длину слова. Фиг, иногда соскакивает позиция, видимо какие-то дополнительные флаги к слову добавлены. В процессе осмысления смотрю на первые восемь байт индекса и вижу что в натуре из них получается указатель на слово, если их умножить на 2 и прибавить 2. Но не всегда. Иногда спрыгивает в дебри куда-то. И старшие два байта вместо 0000 - 2000.

Оказывается, психи, которые писали файл, писали в него бинарные данные побайтно, не отключив конверсию этого дела в юникод. Т.е. каждые 9 байт индекса записывались как 18 байт записи в файле с конверсией странных символов из текущей локали в соответствующие юникодные. И конверсией 00 в пробел, т.е. 00 - 2000.
Вуду-программирование. Сказали людям "сделать юникод-версию", они заменили функции на соответствующие юникодные и все :)
Пришлось составить список юникодных символов, сопоставить методом анализа файла их реальным байтам и написать конвертор. При этом байты 20 и 00 в выходном файле формально неразличимы, пришлось добавить эмпирический анализатор который ищет правильное значение по критерию типа "следующий индекс должен отличаться от предыдущего на длину слова")

[identity profile] vp.livejournal.com 2009-01-01 04:01 pm (UTC)(link)
Да уж :)

[identity profile] archangel-rhn.livejournal.com 2009-01-01 04:30 pm (UTC)(link)
Файл писали не психи. Его писали студенты. Психи сделали бы все иначе, а именно - сделали бы все правильно, более того, изобрели бы что-то новое, не вписывающееся в рамки классического программирования, стандартов, соглашений.

[identity profile] dorogoj.livejournal.com 2009-01-01 06:00 pm (UTC)(link)
В бытность существования компьютеров до ZX-Spectrum'овской эпохи. Паяли с товарищем нечто самопальное (Орион-128 по схемке из журнала радио) а потом стали подключать к этому чуду мышь!!!
Долго мучили осцилограф, анализировали как работает интерфейс RS-232. Приделали несколько операционных усилителей чтобы получить нормальный сигнал, потратили кучу времени а потом оказалось, что сигнал интерфейса мы припаяли на провод питания мышки и!!! из помех по питанию усилителями и т.п. таки восстановили нормальный сигнал и это чудо даже заработало!
Мораль: может есть способ проще? :-)

[identity profile] pakeha-by.livejournal.com 2009-01-02 10:50 am (UTC)(link)
А как работала с этим словарём "оригинальная" прога, если 20 и 00 неразличимы?
Или словарь составлен и всё на этом (никто его не пользует)?