Обработка xor с различными размерами ключей и порядком байтов - PullRequest
1 голос
/ 29 июня 2011

Я играю с декодированием xor через небольшой C-файл и сталкиваюсь с проблемами с порядком байтов ... Я немного застрял в том, как их обойти. Это действительно первый раз, когда я играл глубоко с побитовыми операциями в C.

Если я использую однобайтовый ключ xor и собираю несколько значений, закодированных в xor, в указатель uint8_t, мой базовый код работает нормально. Пройдите по каждому байту, сделайте xor для ключа и сохраните результат в декодированном байтовом массиве / буфере, а затем распечатайте его обратно на консоль.

Однако, если я попробую двухбайтовый ключ xor, тогда начнёт мешать порядок байтов. В настоящее время я вставляю ключ в uint32_t, потому что я не планирую работать с ключами xor больше 32 бит. В системе с прямым порядком байтов ключ xor 0xc39f сохраняется как 0x9fc3. Байты, которые нужно декодировать, имеют порядок байтов с прямым порядком байтов, если я воспроизводлю их по одному байту за раз, но они также переключаются на байты с прямым порядком байтов, если я пытаюсь воспроизводить их по два байта за раз (такого же размера, как клавиша xor ).

Я испытываю соблазн #include <byteswap.h> и затем звоню bswap_32(). Но хотя это будет работать с прямым порядком байтов, это может иметь противоположный эффект на старшем порядке. Я предполагаю, что тогда мне понадобятся уродливые # ifdef, чтобы использовать только bswap_32() для арок с прямым порядком байтов. Я полагаю, для этого должен быть более портативный способ.

Строка произвольной выборки:

g   e   n   e   r   a   t   e
67  65  6e  65  72  61  74  65

Xor 0xc39f

a4  fa  ad  fa  b1  fe  b7  fa


Если я воспроизведу кодированный по xor буфер с двухбайтовыми (uint16_t) указателями, я получу это (через базовый printf):

0xfaa4 0xfaad 0xfeb1 0xfab7


И с четырехбайтовыми указателями (uint32_t):

0xfaadfaa4 0xfab7feb1



Я бы ожидал, что вместо этого получим вместо двухбайтовых указателей:

0xa4fa 0xadfa 0xb1fe 0xb7fa

И четырехбайтовые указатели:

0xa4faadfa 0xb1feb7fa


Мысли



Редактировать: Есть кто-нибудь? Текущие ответы не соответствуют моим потребностям.

Ответы [ 2 ]

2 голосов
/ 29 июня 2011

Вы задумываетесь над этим - просто рассматривайте свой ключ xor как двоичный двоичный объект без порядкового номера и конвертируйте его в собственный uint32_t для производительности:

void xor_encrypt_slow(uint8_t *data, size_t len, uint8_t key[4])
{
    // key is a 4-byte xor key
    size_t i;
    for(i = 0; i < len; i++)
        data[i] ^= key[i % 4];
}

void xor_encrypt_fast(uint8_t *data, size_t len, uint8_t key[4])
{
    // Convert key to a 32-bit value
    uint32_t key32 = *(uint32_t *)key;

    // This assumes that data is aligned on a 4-byte boundary; if not, adjust
    // accordingly
    size_t i;
    for(i = 0; i + 3 < len; i += 4)
        ((uint32_t *)data)[i] ^= key32;
    // Handle the remainder, if len is not a multiple of 4
    for( ; i < len; i++)
        data[i] ^= key[i % 4];
}
0 голосов
/ 29 июня 2011

Попробуйте использовать макрос htonl(), который предназначен именно для этой цели.Он означает «hex to network long» и определен для замены (или не замены) байтов, чтобы сделать результирующие значения старшими, как требуется перед передачей их по сети.

...