Разбор формата истории RnQ

Больше
7 года 6 мес. назад - 7 года 6 мес. назад #1 от Sleuthhound
Sleuthhound создал тему: Разбор формата истории RnQ
Всем привет,

Для плагина RnQHistoryToDB дошла очередь написать импорт истории RnQ в БД.

Нашел в инете программу "Синхронизатор историй", которая помогает объединить историю RnQ из неск. файлов в один. Взял часть информации о структуре истории из неё, часть из исходников R&Q 1105.

Набросал небольшую программку по чтению файла истории, прилагаю её в атаче.

Все бы хорошо, но самое главное поле - само сообщение, никак не удается прочитать, вроде оно и не шифровано если верить исходникам R&Q 1105, но выводится абра кадабра.

По формату:
Вся история идет блоками, насколько я понял структура блока такая:

What: Integer; // Тип блока (4 байта) - HI_event,HI_hashed или HI_cryptMode
Tipe: Byte; // Неизвестное поле (1 байт)
UIN: Integer; // UIN (4 байта)
Time: TDateTime; // Дата и время (8 байта)
ExInfoSize: Integer; // Размер поля расш. информации (4 байта), опытным путем выяснил что блок всегда одного размера - 21 байт
ExInfo: // Поле расш. информации (21 байт)
MsgSize: Integer; // Размер тела сообщения (4 байта)
Msg: AnsiString; // Само сообщение

Вроде как все поля читаются корректно, кроме поля самого сообщения, там абра кадабра.

Вопрос к Rapid D, само тело сообщения при типе блока HI_event = -1 как то кодируется? Или я структуру блока неправильно разложил?

Вложение RnQHistoryReader.rar не найдено

Вложения:
Последнее редактирование: 7 года 6 мес. назад пользователем Sleuthhound.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 6 мес. назад #2 от Rapid D
Rapid D ответил в теме Разбор формата истории RnQ
Sleuthhound писал(а):


What: Integer; // Тип блока (4 байта) - HI_event,HI_hashed или HI_cryptMode
Tipe: Byte; // Неизвестное поле (1 байт)
UIN: Integer; // UIN (4 байта)
Time: TDateTime; // Дата и время (8 байта)
ExInfoSize: Integer; // Размер поля расш. информации (4 байта), опытным путем выяснил что блок всегда одного размера - 21 байт
ExInfo: // Поле расш. информации (21 байт)
MsgSize: Integer; // Размер тела сообщения (4 байта)
Msg: AnsiString; // Само сообщение

Вроде как все поля читаются корректно, кроме поля самого сообщения, там абра кадабра.

Вопрос к Rapid D, само тело сообщения при типе блока HI_event = -1 как то кодируется? Или я структуру блока неправильно разложил?

Вложение RnQHistoryReader.rar не найдено

сообщение всегда кодируется:
f_info:=critted(info_, StrToIntDef(who.uid, 0))
2-е поле наз-ся Kind. Вам лучше расшифровывать когда Kind=EK_msg
ExInfoSize совсем не всегда =21.
Msg - Совсем не AnsiString, а RawByteString.
И текст там не только зашифрован, но и может быть в разных кодировках. Последнее время в основном в UTF8.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 6 мес. назад - 7 года 6 мес. назад #3 от Sleuthhound
Sleuthhound ответил в теме Разбор формата истории RnQ
Rapid D писал(а):

сообщение всегда кодируется:
f_info:=critted(info_, StrToIntDef(who.uid, 0))
2-е поле наз-ся Kind. Вам лучше расшифровывать когда Kind=EK_msg
ExInfoSize совсем не всегда =21.
Msg - Совсем не AnsiString, а RawByteString.
И текст там не только зашифрован, но и может быть в разных кодировках. Последнее время в основном в UTF8.


Все понятно, спасибо, все получилось. История успешно читается.

То что размер ExInfo = 21 байт - это я наврал, он может меняться и вовсе не 21 байт

Остался вопрос: А что содержит блок ExInfo ?
Вложения:
Последнее редактирование: 7 года 6 мес. назад пользователем Sleuthhound.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 6 мес. назад - 7 года 6 мес. назад #4 от Sleuthhound
Sleuthhound ответил в теме Разбор формата истории RnQ
Исходники рабочей программки во вложении.

Единственный баг, это очень редко, но некоторые сообщения остаются все же абра-кадаброй.

Возможно дело в кодировке, хотя после расшифровки я проверяю строку, если она UTF8, то декодирую её.

Вложение RnQHistoryReader-c2dd6992266ed5721e5710a19b12c791.rar не найдено

Вложения:
Последнее редактирование: 7 года 6 мес. назад пользователем Sleuthhound.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 6 мес. назад #5 от Rapid D
Rapid D ответил в теме Разбор формата истории RnQ
StrToIntDef(IntToStr(Res.UIN), 0) - странный код :)

По поводу ExInfo - в исходниках 1105 всё и написано:
function extraInfo:string;
begin
result:=TLV2(EI_flags, int2str(flags));
if not isOnlyDigits(who.UID) then
result:= Result + TLV2(EI_UID, int2str(length(who.UID))+who.UID);
result:=int2str(length(result))+result;
end; // extrainfo

Т.е. если UIN=0, то туда пишется строка с, например, почтой (если это mail.ru контакт или AIM).

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 6 мес. назад - 7 года 6 мес. назад #6 от Sleuthhound
Sleuthhound ответил в теме Разбор формата истории RnQ
Rapid D писал(а):

StrToIntDef(IntToStr(Res.UIN), 0) - странный код :)


Да это я так, на скору руку, так то просто Res.UIN и все ;)

Rapid D писал(а):

По поводу ExInfo - в исходниках 1105 всё и написано:
function extraInfo:string;
begin
result:=TLV2(EI_flags, int2str(flags));
if not isOnlyDigits(who.UID) then
result:= Result + TLV2(EI_UID, int2str(length(who.UID))+who.UID);
result:=int2str(length(result))+result;
end; // extrainfo

Т.е. если UIN=0, то туда пишется строка с, например, почтой (если это mail.ru контакт или AIM).


С этим все ясно стало, спасибо.

Очень жаль, что в файл истории не пишется Никнейм собеседника, а только UIN. При импорте практически не реально понять кто же прячется за определенным номером :(

Может есть планы по доработке формата истории? Добавить пару полезных полей, такие как Никнейм и Количество сообщений. А то пока не прочитаешь весь файл, то не понятно сколько же всего в нем сообщений, накладно это очень. Про отсутствие Ника уже написал.
Последнее редактирование: 7 года 6 мес. назад пользователем Sleuthhound.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 6 мес. назад - 7 года 6 мес. назад #7 от cy6
cy6 ответил в теме Разбор формата истории RnQ
Sleuthhound писал(а):

Очень жаль, что в файл истории не пишется Никнейм собеседника, а только UIN. При импорте практически не реально понять кто же прячется за определенным номером :(

Может есть планы по доработке формата истории? Добавить пару полезных полей, такие как Никнейм и Количество сообщений. А то пока не прочитаешь весь файл, то не понятно сколько же всего в нем сообщений, накладно это очень. Про отсутствие Ника уже написал.


Поля переменной длинны, это не последние сюрпризы, которые вам могут встретится. Смотрим, например, в сторону протокола мыл-агента и плагинов, пихающих в историю картинки неприличных размеров. :silly:
Если любопытно, взгляните на исходники и историю создания RnQ_Repair. Могу также поделится не выложенными более свежими.

Никнеймы берутся элементарно из {%Root_RNQ%}\{%UIN%}\db5:db. Файлик db5 распаковываем любым алгоритмом с поддержкой Zip. Я пользуюсь zlib + minizip, последний в собственной адаптации.

Файлы истории уже достаточно перегружены "пестрым" составом данных, имхо.
А писать избыточные данные (которые могут быть получены путем вычисления или доступа к другим объектам), вообще плохой стиль. Дублирование информации используется для увеличения производительности (например поисковые ключи (индексы)), но у нас совсем не тот случай и не те объемы данных, имхо.

А количество сообщений все равно станет известно, так как файл все равно придется читать весь,
для конвертации. Это же связанный список, типа Next->Next. Хоть на стриммерную ленту пиши. :)

Sleuthhound писал(а):

Единственный баг, это очень редко, но некоторые сообщения остаются все же абра-кадаброй.
Возможно дело в кодировке, хотя после расшифровки я проверяю строку, если она UTF8, то декодирую её.

А может не все варианты кодировки учли, или там вообще текста нет? :silly:
Я для декода написала вот такую функцию:
procedure FastDetectCharset(S: AnsiString; var CountUTF8, CountWin, CountUTF, CountUTFBE: Integer);
Последнее редактирование: 7 года 6 мес. назад пользователем cy6.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 6 мес. назад #8 от Sleuthhound
Sleuthhound ответил в теме Разбор формата истории RnQ
cy6 писал(а):

Поля переменной длинны, это не последние сюрпризы, которые вам могут встретится. Смотрим, например, в сторону протокола мыл-агента и плагинов, пихающих в историю картинки неприличных размеров. :silly:


С такими полями у меня вроде нет проблем. Удручает закрытость формата истории некоторыx меcсенждеров, к примеру QIP. :(

Если любопытно, взгляните на исходники и историю создания RnQ_Repair. Могу также поделится не выложенными более свежими.


Был бы очень благодарен, если поделитесь исходниками. Обещаю что никуда не уйдут.

Никнеймы берутся элементарно из {%Root_RNQ%}\{%UIN%}\db5:db. Файлик db5 распаковываем любым алгоритмом с поддержкой Zip. Я пользуюсь zlib + minizip, последний в собственной адаптации.


DB5 начал использоватся в сравнительно новых версиях RnQ, то есть по уму нужно еще и поддержку DB4 делать. Попробую брать данные оттуда. Спасибо за подсказку.

Файлы истории уже достаточно перегружены "пестрым" составом данных, имхо.
А писать избыточные данные (которые могут быть получены путем вычисления или доступа к другим объектам), вообще плохой стиль.


А если файл db5 не доступен? Собственно вот и приплыли. Избыточность не всегда отрицательна, иногда она очень даже полезна. Чем дергаться и разгребать 2 файла - файл истории + файл db5, проще добавить "избыточное поле" в файл истории и тем самым в разы упростить работу и себе и другим. Поле длиною 10-30 байт никак не повредит, ИМХО.

А количество сообщений все равно станет известно, так как файл все равно придется читать весь,
для конвертации. Это же связанный список, типа Next->Next. Хоть на стриммерную ленту пиши. :)


А если мне не нужно его весь читать? Нужно просто знать количество сообщений, как бы статистические данные. А тут приходится его весь читать. Ладно если там 1000 сообщений, а у меня допустим есть файлы истории в которых более 50 тыс. сообщений. На не быстром компьютере чтение таких файлов занимает несколько больше времени чем следовало бы. И это ради того чтобы узнать 1 цифру.

Sleuthhound писал(а):

Единственный баг, это очень редко, но некоторые сообщения остаются все же абра-кадаброй.
Возможно дело в кодировке, хотя после расшифровки я проверяю строку, если она UTF8, то декодирую её.

А может не все варианты кодировки учли, или там вообще текста нет? :silly:
Я для декода написала вот такую функцию:
procedure FastDetectCharset(S: AnsiString; var CountUTF8, CountWin, CountUTF, CountUTFBE: Integer);
[/quote]

в WideStrUtils есть функция IsUTF8String, вот её я и использую для определения UTF8 строка или нет. Если UTF8, то делаем UTF8Decode. Конечно если строка в какой-нибудь другой кодировке, то получается абра-кадабра.

Не поделитесь своей процедуркой FastDetectCharset?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 6 мес. назад - 7 года 6 мес. назад #9 от cy6
cy6 ответил в теме Разбор формата истории RnQ
Sleuthhound писал(а):

Был бы очень благодарен, если поделитесь исходниками. Обещаю что никуда не уйдут.
...
в WideStrUtils есть функция IsUTF8String, вот её я и использую для определения UTF8 строка или нет. Если UTF8, то делаем UTF8Decode. Конечно если строка в какой-нибудь другой кодировке, то получается абра-кадабра.

Не поделитесь своей процедуркой FastDetectCharset?

Смотрите файл Decode.pas в исходниках на предмет FastDetectCharset.
Ссылка на исходники и пароль в теме утилиты/плагина RnQ_Repair. :)

Не выложенные более свежие, тоже кину, как только откопаю на диске. :silly:
Их содержимое касается некоторых хитро-мудростей нечасто встречающихся данных в истории, а также увеличения производительности класса файлового I/O.
Последнее редактирование: 7 года 6 мес. назад пользователем cy6.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 6 мес. назад #10 от Sleuthhound
Sleuthhound ответил в теме Разбор формата истории RnQ
cy6 писал(а):

Смотрите файл Decode.pas в исходниках на предмет FastDetectCharset.
Ссылка на исходники и пароль в теме утилиты/плагина RnQ_Repair. :)


Взял процедуру FastDetectCharset, с ней абсолютно все сообщения нормально декодируются. Огромное спасибо!

cy6 писал(а):

Не выложенные более свежие, тоже кину, как только откопаю на диске. :silly:
Их содержимое касается некоторых хитро-мудростей нечасто встречающихся данных в истории, а также увеличения производительности класса файлового I/O.


Было бы любопытно посмотреть на предмет ускорения чтения и распарсивания файлов истории. Спасибо.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 6 мес. назад #11 от Sleuthhound
Sleuthhound ответил в теме Разбор формата истории RnQ
К разговору где взять сопоставление UIN <> Nickname, распаковываю файл db5 обычным unzip, там куча файлов, насколько я понял вся нужная инфа лежит в файле db, но он бинарный.

А какой у него формат? Какой-то общеизвестный или опять ковырять исходники нужно?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 4 мес. назад - 7 года 4 мес. назад #12 от boulder
boulder ответил в теме Разбор формата истории RnQ
Неожиданно полетел винчестер. Поиск по названиям файлам ничего не даёт, но данные должны были остаться, места там хватало для всего. Уважаемые гуру, подскажите, пожалуйста, маркер — цепочку байтов, по которой можно найти файлы истории?! :) "FF FF FF FF 01 9C EF 38" в начале файла — не она ли это? :S
Последнее редактирование: 7 года 4 мес. назад пользователем boulder.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 4 мес. назад #13 от Mikanoshi
Mikanoshi ответил в теме Разбор формата истории RnQ
boulder
FF FF FF FF только в начале всех файлов истории, дальше другие байты, так что по этому их не найти

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
7 года 4 мес. назад - 7 года 4 мес. назад #14 от boulder
boulder ответил в теме Разбор формата истории RnQ
Мда, и концовки разные... А внутри? :( Неужели нет общей сигнатуры для всех файлов?
Последнее редактирование: 7 года 4 мес. назад пользователем boulder.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Модераторы: dekRapid D
Время создания страницы: 0.494 секунд
Работает на Kunena форум