PS: Если я изменяю оператор в char baseStr [], вывод неправильный, почему? Например, если значение baseStr равно Test, выходные данные будут:
Encrypted: *?�
Decrypted:Test�&
Это связано с тем, что encryptDecrypt
использует strlen
для определения конца "строки". strlen
полагается на чтение нулевого байта для определения конца строки. При шифровании у вас есть нулевая завершенная строка. Но шифрование не создает строку с нулевым символом в конце, оно создает поток байтов, который не завершается нулем.
Мы можем это исправить.
void encryptDecrypt(char *input, char *output) {
char key[] = {'K', 'C', 'Q'}; //Can be any chars, and any size array
size_t len = strlen(input);
for(size_t i = 0; i < len; i++) {
printf("%zu\n", i);
output[i] = input[i] ^ key[i % (sizeof(key)/sizeof(char))];
}
output[len] = '\0';
}
Я не знаю, это хорошее решение. strlen
, вероятно, небезопасно для расшифровки, поскольку может быть возможно, что байт зашифрованной строки содержит нулевой байт. Может быть разумнее, чтобы функция принимала длину ввода.
void encryptDecrypt(char *input, char *output, size_t *strlen)
// We know baseStr is a string and can use strlen.
char encrypted[strlen(baseStr)];
encryptDecrypt(baseStr, encrypted, strlen(baseStr));
// The encrypted string is the same length as `baseStr`.
char decrypted[strlen(baseStr)];
encryptDecrypt(encrypted, decrypted, strlen(baseStr));
output[i] = input[i] ^ key[i % (sizeof(key)/sizeof(char))];
(sizeof(key)/sizeof(char))
получает число элементов в key
. sizeof
производит количество байтов. Таким образом, (sizeof(key)/sizeof(char))
производит количество элементов путем деления размера массива на размер каждого элемента.
char
всегда равен 1 байту, мы можем избавиться от sizeof(char)
, чтобы сделать вещи немного проще.
output[i] = input[i] ^ key[i % sizeof(key)];
Это делает xor каждого символа input
с каждым символом key
. Поскольку key
и input
, вероятно, имеют различную длину, а key
, вероятно, короче , it must wrap around and reuse the
key again.
% `является оператором модуля, он разделит и оставит остаток.
- 0% 3 = 0
- 1% 3 = 1
- 2% 3 = 2
- 3% 3 = 0
- 4% 3 = 1
Это также называется "математикой часов".
Таким образом, первый символ input
является xor'd с первым символом key
, второй со вторым, третий с третьим, но четвертый символ input
- это xor'd с первым символом key
.
Это можно увидеть в действии, напечатав i
и Индекс ключа.
for(size_t i = 0; i < len; i++) {
printf("%zu\n", i);
size_t ki = i % sizeof(key);
printf("i = %zu, ki = %zu\n", i, ki);
output[i] = input[i] ^ key[ki];
}