Мне нужно написать код, который шифрует char специальным ключом. Я должен использовать собственный ключ и маску с операцией XOR. Но у меня проблема с пониманием и реализацией этого.

Во-первых, я создал свой собственный ключ, который использую для шифрования символа. Этот ключ является числом e.q: 123456789. В двоичном представлении число 123456789: 00010101 11001101 01011011 00000111. Я разделил его на 4 x 8 бит, потому что я ввел тип char. Я тоже должен использовать это, чтобы зашифровать свой символ с помощью маски. Моя маска - 0xFF, потому что она сбрасывает самые старые биты, а самые молодые 8 бит остаются для работы с операцией XOR. Это означает, что когда я ввожу символ "a", он должен зашифровать это с помощью этого ключа и маски с помощью операции XOR.

Более того, я хотел проверить, что мой компилятор показывает с позицией ключа [0]. Это означает, что у меня есть "int key [0] = {00000111}". Я думаю, он должен отображать число 7 как двоичное число, но компилятор показывает число 73. Почему?

Буду признателен, если кто-нибудь поможет мне решить эту проблему.

Вот мой код:

#include <iostream>

using namespace std;


void encryption(char chars[], const int size);

int main() {
    const int size1 = 4;
    char chars1[size1];
    unsigned int keys = 123456789;
    int key[] = {00000111}; // why does it show number 73 instead of 7 ?

    cout << "Enter a char to encrypt: " << endl;
    cin >> chars1[0];


    return 0; }

void encryption(char chars[], const int size) {
    unsigned int keys = 123456789;
    unsigned int key[] = {00010101, 11001101, 01011011, 00000111};
    unsigned int mask = 0xFF;
    int temp[4] = {0};


        temp[0] = chars[0] ^ (keys & mask);
        temp[1] = chars[0] ^ ((keys >> 8) & mask);
        temp[2] = chars[0] ^ ((keys >> 16) & mask);
        temp[3] = chars[0] ^ ((keys >> 24) & mask);

}
1
gryzek 16 Апр 2016 в 23:44

2 ответа

Лучший ответ

Есть несколько проблем:

  1. unsigned int keys = 123456789 в шестнадцатеричном формате 075bcd15
    00010101, 11001101, 01011011, 00000111 в шестнадцатеричном формате 15cd5b07
    Хотя оба они 4-байтовые, обратите внимание на обратный порядок байтов, потому что компьютер использовал так называемый порядок байтов с прямым порядком байтов для целых чисел. Поэтому, если вы получаете байты путем преобразования к беззнаковому символу, вы получите обратный порядок байтов, который вы ожидаете.

  2. unsigned int key[] - это массив int, который кажется 32-битным (4-байтовым).

Для одного unsigned int используйте
unsigned int keyBytes3 = {0x075bcd15};

Для массива из 4 unsigned char:
unsigned char keyBytes[] = {0x07, 0x5b, 0xcd, 0x15};

Лично для случаев, когда размер имеет значение, я предпочитаю использовать типы uint32_t и uint8_t, тогда это не касается размеров, int может быть больше или меньше 32-битного в зависимости от процессора.

0
zaph 17 Апр 2016 в 15:38

Проблема в том, что компилятор не интерпретирует ваш 00000111 как двоичный. C ++ 11 не поддерживает двоичные литералы. Кроме того, любое число, которое начинается с 0 (также известного как 00000111) в качестве старшей цифры, считается восьмеричным. В восьмеричном формате 111 эквивалентен десятичному 73.

Вам нужно будет преобразовать все ваши «двоичные значения» в десятичные, а затем использовать их. Или вы можете использовать boost, у которого есть утилита, которая обрабатывает вы хотите сделать.

0
cehnehdeh 16 Апр 2016 в 21:14