2013-09-08 1 views
1

У меня есть этот кусок кода здесьExtra 0xFFFFFF во время шифрования исключающего

#include<stdio.h> 

#define LEN 10 

char buf[] = {0xff,0xaa,0xfc,0xe8,0x89,0x00,0x00,0x00,0x60,0x89}; 
char key[] = "SAMPLE KEY"; 

int main() 
{ 
     int i; 
     char enc[LEN]; 
     for(i=0;i<LEN;i++) 
     { 
       enc[i] = (key[i % LEN]^buf[i]); 
       printf("0x%x,",enc[i]); 
     } 
} 

который выводит

ВЫВОД

0xffffffac,0xffffffeb,0xffffffb1,0xffffffb8,0xffffffc5,0x45,0x20,0x4b,0x25,0xffffffd0 

где ожидается выход

0xac,0xeb,0xb1,0xb8,0xc5,0x45,0x20,0x4b,0x25,0xd0, 

Как я могу это исправить? Почему это происходит?

ответ

3

Изменение buf и enc типа при объявлении от char до unsigned char.

Это определяется реализацией ли char является signed или unsigned типа и в вашей реализации это очевидно signed типа.

+0

Это работает, потому что что-либо с битом знака (бит 7) будет расширяться путем неявного преобразования с выходными функциями. – Joe

+0

+1 Спасибо, Это сработало как шарм, но не могли бы вы объяснить, почему у нас есть эта проблема ... – vikkyhacks

+1

@vikkyhacks: Вы переполнили значение, которое может удерживать символ 'char'.В вашей реализации «char» подписан, и это почти наверняка дополнение восьми бит. Это означает, что он может содержать только значения от -128 до 127. Исходный текст '0xff' означает номер 255, который больше, чем ваш' char' может удерживать. Поэтому он переполнился. В вашей реализации C он сохранил бит 11111111 в символе. Эти биты представляют значение -1. Когда подписанный 'char' со значением -1 передается' printf', ему присваивается 'int'. Результатом является «int» со значением -1, которое представлено битами 0xffffffff. –

0

Прямо сейчас у вас есть не только ведущие знаковые биты, но и отсутствующие ведущие нули.

Использование

printf("0x%02x,", enc[i] & 0xFFu); 
+0

(a) OP не указывает, что требуются ведущие нули. (b) Это не фиксирует поведение, определяемое реализацией инициализации подписанных объектов 'char' со значениями, которые переполняются. –

+0

@ Эрик: объявление 'buf' в исходном источнике является сильным намеком на то, что да, нужные начальные нули. –

1

Ваше шифрование работает отлично. Проблема заключается в том, что вы объявили enc как массив , подписанный символами. (Как ouah правильно отмечает, char могут быть подписаны или без знака по умолчанию. На вашем компилятор, это, видимо, подписано.)

Таким образом, символы, такие как 0xAC, которые имеют свой набор MSB интерпретируются как отрицательные числа. Когда вы передаете их printf(), они неявно преобразуются в int и, следовательно, sign-extended - 32 бита.

Чтобы исправить это, просто объявить enc, key и buf в явном виде массивов unsigned char с. В качестве альтернативы вы могли бы использовать решение Бена Вейгта и маскировать лишние биты, но тогда вы бы бессмысленно подписывали свои символы только для того, чтобы снова скрыть лишние биты.

Ps. Вы понимаете, что такой «шифрование» безнадежно слаб, если вы шифруете что-либо значительно дольше, чем ключ, верно?

+0

благодарит ваш комментарий о шифровании. Я планирую использовать ключ, пока сам текст, я знаю, что это плохая идея, но я считаю это хорошим в моем случае здесь. Это просто, быстро и легко работать, чем некоторые сложные методы шифрования. – vikkyhacks

0

ОП использует формат, обозначенный %x для unsigned.

Поскольку значение char становится int с printf() ... параметрами, используйте формат %hhx предназначенные для char. Это напечатает только часть char. Пример:

printf("0x%02hhx,",enc[i]); --> 0xac, 
+0

Это не фиксирует поведение, определяемое реализацией инициализации подписанных объектов 'char' со значениями, которые переполняются. Кроме того, он оставляет объекты, определенные как «char», которые будут иметь отрицательные значения и дают неожиданные результаты в других ситуациях, таких как смещение битов. –

+0

@Eric Postpischil Я согласен с тем, что код OP имеет проблему переполнения, о которой вы упомянули, но это не вызвало этой проблемы. Согласитесь, что проблема смещения бит корректна, но фрагмент OP не использует сдвиг. Я предположил, что OP хотел использовать 'char' по какой-то неопределенной причине. Проблема OP была с печатью будет решена с помощью формата 'hhx'. Это можно использовать с символом 'char' или' unsigned char'. – chux