Vigenere шифрование декодирования не работает должным образом - PullRequest
0 голосов
/ 09 ноября 2018

Я пишу шифр Vigenere, который будет использоваться как часть загружаемого модуля ядра. Таким образом, я не могу использовать библиотеку строк. Вот почему я включил отдельные циклы для получения длины ключа и ввода. Оператор include и main включены только для тестирования.

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

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

==25694==ERROR: AddressSanitizer: BUS on unknown address 0x00010c98ae80 (pc 0x00010c989ac2 bp 0x7ffee3277610 sp 0x7ffee3277440 T0)
    #0 0x10c989ac1 in encrypt (vig:x86_64+0x100001ac1)
    #1 0x10c98aca1 in main (vig:x86_64+0x100002ca1)
    #2 0x7fff5c419ef8 in start (libdyld.dylib:x86_64+0x16ef8)

==25694==Register values:
rax = 0x000000010c98ae80  rbx = 0x00007ffee3277440  rcx = 0x000000010c98ae4b  rdx = 0x0000000000000004  
rdi = 0x000000010c98ae80  rsi = 0x000000010c98ae4b  rbp = 0x00007ffee3277610  rsp = 0x00007ffee3277440  
 r8 = 0x00001000219315d0   r9 = 0x0000000000000004  r10 = 0x0000000000000000  r11 = 0x0000000000000000  
r12 = 0x0000000000000000  r13 = 0x0000000000000000  r14 = 0x0000000000000000  r15 = 0x0000000000000000  
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: BUS (vig:x86_64+0x100001ac1) in encrypt
==25694==ABORTING
Abort trap: 6

Вот мой код:

#include<stdio.h>
#include<stdlib.h>
char* encrypt(char* input, char* key)
{
    int keyLength = 0;
    int inputLength = 0;
    int i;
    int j;
    for(i = 0; key[i] != '\0'; i++) //Get the length of the key
    {
        keyLength++;
    }
    for(i = 0; input[i] != '\0'; i++) //Get the length of the input
    {
        inputLength++;
    }
    for (i = 0; i < keyLength; i++)
    {
        if(key[i] >= 'a' && key[i] <= 'z')
        {
             key[i] = key[i] - 'a' + 'A';
        }
    }

    char* encryptedMessage = (char *)malloc((inputLength+1)*sizeof(char)); //Malloc for the encrypted message
    char fixedKey[inputLength + 1];
    if(inputLength < keyLength)
    {
        for(i =0; i < inputLength; i++)
        {
            fixedKey[i] = key[i];
        }
    }
    for(i = 0, j = 0; i < inputLength; ++i, ++j) //If the key length is shorter than message length, loop the key to correct length
    {
        printf("Entered Loop\n");
        if(j == keyLength)
            j = 0;
        fixedKey[i] = key[j];
    }
    fixedKey[i] = '\0';
    for(i = 0; i < inputLength; ++i) //Encryption
    {
        if(input[i] == ' ')
        {
            encryptedMessage[i] = ' ';
            continue;
        }
        encryptedMessage[i] = ((input[i] + fixedKey[i]) % 26) + 'A';
    }
    encryptedMessage[i] = '\0';
    return encryptedMessage;
}
char* decrypt(char* input, char* key)
{
    int keyLength = 0;
    int inputLength = 0;
    int i;
    int j;
    for(i = 0; key[i] != '\0'; i++) //Get the length of the key
    {
        keyLength++;
    }
    for(i = 0; input[i] != '\0'; i++) //Get the length of the input
    {
        inputLength++;
    }
    for (i = 0; i <keyLength; i++)
    {
        if(key[i] >= 'a' && key[i] <= 'z')
        {
            key[i] = key[i] - 'a' + 'A';
        }
    }
    char* decryptedMessage = (char *)malloc((inputLength+1)*sizeof(char));
    char fixedKey[inputLength + 1];
    if(inputLength < keyLength)
    {
        for(i =0; i < inputLength; i++)
        {
            fixedKey[i] = key[i];
        }
    }
    for(i = 0, j = 0; i < inputLength; ++i, ++j) //Fix the key length if needed
    {
        if(j == keyLength)
            j = 0;
        fixedKey[i] = key[j];
    }
    fixedKey[i] = '\0';
    for(i = 0; i < inputLength; ++i) //Decryption
    {
        if(input[i] == ' ')
        {
            decryptedMessage[i] = ' ';
            continue;
        }
        decryptedMessage[i] = (((input[i] - fixedKey[i]) + 26) % 26) + 'A';
    }
    decryptedMessage[i] = '\0';
    return decryptedMessage;
}
int main()
{
    char* encrypted = encrypt("The quick brown fox jumps over lazy dogs","key");
    char* decrypted = decrypt(encrypted,"key");
    printf("Encrypted string is: %s\nDecrypted String is: %s\n",encrypted,decrypted);
    return 0;
}

1 Ответ

0 голосов
/ 09 ноября 2018

Вы пытаетесь изменить строковый литерал.

Вы звоните encrypted как:

encrypt("The quick brown fox jumps over lazy dogs","key");

Затем в encrypt вы изменяете второй параметр:

key[i] = key[i] - 'a' + 'A';

Строковые литералы доступны только для чтения, и попытка их изменения вызывает неопределенное поведение .

Сделайте локальную копию key и измените ее при выполнении преобразования в верхний / нижний регистр.

...