Шифрование XOR с 32-битным int и массивом из четырех символов в C - PullRequest
0 голосов
/ 31 января 2020

Я пытаюсь реализовать простую функцию шифрования XOR, которая принимает 32-разрядное целое число без знака (big endian), а также ключ в виде четырехбуквенного массива символов. Затем XOR сравнивает первые восемь битов int с первым символом, затем следующие восемь битов со следующим символом и т. Д. c. Ниже приведено то, что у меня есть, хотя он выводит 0 в результате шифрования 8/10 раз:

unsigned int EncryptXOR(unsigned int x, unsigned char key[]) {
  unsigned int result = 0; // int to hold final result
  unsigned char* ascii; // pointer for chars in key array
  unsigned char* num; // pointer for each 8 bit segment in x
  unsigned int* encryption; // pointer for result
  int i;

  ascii = (unsigned char*)&key;
  num = (unsigned char*)&x;
  encryption = &result;

  for (i=0; i<4; i++) {
    *(encryption+i) = ascii[i] ^ num[i]; // for each byte in result, change to XOR of ascii and num
  }
  return result; // return changed result
}

Мои логики c с этим я беру сегменты х (число, которое будет зашифрованы) и символы, XOR их, а затем установить каждый сегмент результата с этим новым значением XORed. Затем я возвращаю результат, потому что указатель шифрования должен был обновить свои значения, верно? Я новичок в C, поэтому у меня может быть очевидная логика c или ошибка кодирования, которая, будем надеяться, будет очевидна для кого-то более опытного.

1 Ответ

2 голосов
/ 31 января 2020

Проблема, с которой вы столкнулись, связана с арифметикой указателя c в этой строке:

*(encryption+i) = ascii[i] ^ num[i];

Теперь, поскольку переменная encryption определена как int*, добавление, i будет автоматически умножено на sizeof(int) компилятором. Поэтому код, подобный следующему, будет работать как положено:

int array[4] = {1, 2, 3, 4};
int *ptr = &array[0];
*(ptr+2) = 5; // Will actually add "2 * sizeof(int)" to "ptr" - referencing THIRD element of array

Что вы можете сделать, это объявить encryption как указатель на unsigned char:

unsigned char* encryption = (unsigned char*)(&result);

Не стесняйтесь просить дальнейших разъяснений и / или объяснений; Вы также можете найти Pointer Arithmeti c раздел этого учебного пособия полезным.

РЕДАКТИРОВАТЬ: лучший / более безопасный способ добиться шифрования - использовать бит оператор -shift (<<) для перемещения элементов массива символов в соответствующие байты переменной result, затем XOR, что (одним падением sw oop) с аргументом x. Итак, как вы указали формат Big-Endian , вы можете использовать такой код:

unsigned int EncryptXOR(unsigned int x, unsigned char key[]) {
  unsigned int mask = (key[0] << 24) | (key[1] << 16) | (key[2] << 8) | key[3];
  return x ^ mask;
}
...