Может кто-нибудь помочь мне определить алгоритм? - PullRequest
1 голос
/ 25 марта 2011

В этом проприетарном сетевом протоколе используется странный (CRC?) Алгоритм хеширования, которого я раньше не видел.Он рассчитывает это по порту.

Из исследования я получил следующие хэши:

0-85
1-84
85-d0

7770-df
7771-de
7772-c9
7773-d0
7774-db
7775-da 
7776-e5 
7777-e4
7778-e7

Это отправляется в 0x03 пакета соединения и изменяется в зависимости от номера порта.

Спасибо,

1 Ответ

1 голос
/ 25 марта 2011

Для однобайтовых входов алгоритм:

f x = 0x80 .|. (0xF0 .&. x `shiftL` 4) .|. x `xor` 0x05

или в стиле C:

#define F(x) (0x80 | (0xF0 & (x << 4)) | (x ^ 0x05))

РЕДАКТИРОВАТЬ: я изменил 0xF в 0xF0, которыйчто я имею в виду.

Соответствует приведенным примерам (необходимо больше примеров).

Вам недостаточно двухбайтовых примеров (см. мой комментарий), поэтому я не буду беспокоиться о них.

РЕДАКТИРОВАТЬ: Как я с этим справился:

Шаг первый: запишите все в битах, пробел разделяйте отрывки (4 бита), потому что дизайны часто делают что-то другое награница клева - то есть они могут x & 0x80 | x ^ 0x05, но реже x & 0x84 | x ^ 0x01.

0000 0000 --> 1000 0101
0000 0001 --> 1000 0100

Видите, похоже, что мы получаем 0x80 бесплатно (или), а второй клев получилxor 0x05.Тестирование 0 и 1 было умным.Дистанция Хэмминга, одно значение и нулевые значения всегда хорошие тесты.Итак, сейчас я думаю, что alg:

#define f(x) (x ^ 0x85)

Затем мы получим тестовую пару от 0x85 до 0xd0:

1000 0101 --> 1101 0000

Так что нижний клев по-прежнему выглядит правильно (xor с 0x05) но верхний полубайт должен измениться на ИЛИ, а не на XOR:

#define f(x) ( (0xF0 & x | 0x80) \ // Upper nibble
             | 0x0F & (x ^ 0x05))   // Lower nibble

Это то же самое, что и

#define f(x) ( x^0x05 | 0x80)

Но это все еще не делает этого!Обратите внимание, что в нашем результирующем верхнем полубайте мы получаем тот же битовый шаблон, что и во входном нижнем полубайте, видите 0101?Позволяет ИЛИ нижнему клеву с верхним и называть его верхним:

#define f(x) ( (x^0x05) | 0x80 | (0xF0 & (x << 4))

А теперь мы сопоставим все три тестовых случая (что на самом деле немного)

Это нене то, что я изложил выше, что вы приняли, возможно, вы исправили мою опечатку 0xF в предполагаемом 0xF0?Если нет, то убедитесь, что вы заметили эту ошибку и изменили свой код.Вы могли бы даже включить несколько модульных тестов с известным ответом, если это для какого-либо серьезного использования.

О, и, так как он у меня под рукой, здесь он в рабочем состоянии.

#include <stdio.h>
#define F(x) (0x80 | (0xF0 & (x << 4)) | (x ^ 0x05))

void main()
{
        printf("%02x %02x %02x\n", F(0), F(1), F(0x85));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...