О психах и Unicode
Подкинули безумную задачку - есть бинарный файл-словарь. Нужно из него вытащить список слов и вставить в другой словарь.
Ну сел разбираться. Вижу - классика, в начале файла гигантский индекс из записей постоянной структуры с указателями(они на глаз хорошо видны, периодическая структура), после него идут список слов, слова переменной длины. Задача простейшая - определить длину и формат записи индекса, вычитать слова и сохранить в что-то более вменяемое.
Слова в юникоде, и самое главное - в начале файла есть unicode byte order mark(FFFE).
Высчитал длину записи индекса, сдампил его с длиной строки равной длине записи, и смотрю - ну что-то странное откровенно. Вижу что нарастающие указатели, вижу что данные бинарные, но при этом - формат явно уникод, т.е. байт, 0, байт, 0, иногда байт,20, итд.
Ну ладно, сначала думаю, найду где длина слова живет. Взял три слова с начала, посчитал длину, сразу же увидел где она в индексе. Решил почитать пока чисто через длину слова. Фиг, иногда соскакивает позиция, видимо какие-то дополнительные флаги к слову добавлены. В процессе осмысления смотрю на первые восемь байт индекса и вижу что в натуре из них получается указатель на слово, если их умножить на 2 и прибавить 2. Но не всегда. Иногда спрыгивает в дебри куда-то. И старшие два байта вместо 0000 - 2000.
Оказывается, психи, которые писали файл, писали в него бинарные данные побайтно, не отключив конверсию этого дела в юникод. Т.е. каждые 9 байт индекса записывались как 18 байт записи в файле с конверсией странных символов из текущей локали в соответствующие юникодные. И конверсией 00 в пробел, т.е. 00 - 2000.
Вуду-программирование. Сказали людям "сделать юникод-версию", они заменили функции на соответствующие юникодные и все :)
Пришлось составить список юникодных символов, сопоставить методом анализа файла их реальным байтам и написать конвертор. При этом байты 20 и 00 в выходном файле формально неразличимы, пришлось добавить эмпирический анализатор который ищет правильное значение по критерию типа "следующий индекс должен отличаться от предыдущего на длину слова")
Ну сел разбираться. Вижу - классика, в начале файла гигантский индекс из записей постоянной структуры с указателями(они на глаз хорошо видны, периодическая структура), после него идут список слов, слова переменной длины. Задача простейшая - определить длину и формат записи индекса, вычитать слова и сохранить в что-то более вменяемое.
Слова в юникоде, и самое главное - в начале файла есть unicode byte order mark(FFFE).
Высчитал длину записи индекса, сдампил его с длиной строки равной длине записи, и смотрю - ну что-то странное откровенно. Вижу что нарастающие указатели, вижу что данные бинарные, но при этом - формат явно уникод, т.е. байт, 0, байт, 0, иногда байт,20, итд.
Ну ладно, сначала думаю, найду где длина слова живет. Взял три слова с начала, посчитал длину, сразу же увидел где она в индексе. Решил почитать пока чисто через длину слова. Фиг, иногда соскакивает позиция, видимо какие-то дополнительные флаги к слову добавлены. В процессе осмысления смотрю на первые восемь байт индекса и вижу что в натуре из них получается указатель на слово, если их умножить на 2 и прибавить 2. Но не всегда. Иногда спрыгивает в дебри куда-то. И старшие два байта вместо 0000 - 2000.
Оказывается, психи, которые писали файл, писали в него бинарные данные побайтно, не отключив конверсию этого дела в юникод. Т.е. каждые 9 байт индекса записывались как 18 байт записи в файле с конверсией странных символов из текущей локали в соответствующие юникодные. И конверсией 00 в пробел, т.е. 00 - 2000.
Вуду-программирование. Сказали людям "сделать юникод-версию", они заменили функции на соответствующие юникодные и все :)
Пришлось составить список юникодных символов, сопоставить методом анализа файла их реальным байтам и написать конвертор. При этом байты 20 и 00 в выходном файле формально неразличимы, пришлось добавить эмпирический анализатор который ищет правильное значение по критерию типа "следующий индекс должен отличаться от предыдущего на длину слова")
no subject
no subject
no subject
Долго мучили осцилограф, анализировали как работает интерфейс RS-232. Приделали несколько операционных усилителей чтобы получить нормальный сигнал, потратили кучу времени а потом оказалось, что сигнал интерфейса мы припаяли на провод питания мышки и!!! из помех по питанию усилителями и т.п. таки восстановили нормальный сигнал и это чудо даже заработало!
Мораль: может есть способ проще? :-)
(no subject)
no subject
Или словарь составлен и всё на этом (никто его не пользует)?
(no subject)