为什么加密代码会给出问号,而文本包含 s 后的字母并且密钥是 13?

问题描述

所以,我正在编写一个加密代码。我的代码接受单词或任何消息,并要求用户输入密钥。最终输出是加密的消息。例如:

use zip::read::ZipArchive;
use std::io::{Read,Seek};

trait SeekRead: Seek + Read {}

pub struct ArchiveZip<'a,T: SeekRead> {
    filename: &'a str,zip_archive: Box<ZipArchive<T>>,}

但是有一个问题。当我输入包含 Please enter the text you want to encrypt: hello Enter the key: 4 The encrypted text is: lipps 的文本时,它会为加密提供一个问号:

s

当我写其他键而不是 13 并且字母是大写时,不会出现此问题。当文本包含任何在 s (t,v,u,w,x,y,z) 之后的字母且键为 13 时,就会发生此问题。

上述代码为:

Please enter the text you want to encrypt: ssss
Enter the key: 13
The encrypted text is: ����

解决方法

问题出在 ch = ch + key; 行中,当 chkey 的总和大于 char 变量中可以存储的值时。例如,对于字符 's'(ASCII 值 115)和 key13,总和为 128 - 它溢出一个 8 位 signed char(最大值 127)并产生负数。

问题不太可能发生在大写字符上(除非 key 的值非常大),因为它们的 ASCII 值要低得多('A' 到 'Z' 是 65 … 90,而“a”到“z”是 97 … 122)。

要解决此问题,请将“临时”ch 变量设为 int,并在 all 之后将其转换回 char em> 计算完成:

#include <stdio.h>
#include <string.h>

int main(void)
{
    int i,ch; // Use an int for our temporary "ch" variable
    int key;
    char text[101];
    printf("Please enter the text you want to encrypt: ");
    fgets(text,sizeof(text),stdin);
    printf("Enter the key: ");
    scanf("%i",&key);
    for (i = 0; text[i] != '\0'; ++i) {
        ch = text[i];
        if (ch >= 'a' && ch <= 'z') {
            ch = ch + key;
            if (ch > 'z') {
                ch = ch - 'z' + 'a' - 1;
            }
            text[i] = (char)ch; // Cast the int to a char to avoid compiler warnings
        }
        else if (ch >= 'A' && ch <= 'Z') {
            ch = ch + key;

            if (ch > 'Z') {
                ch = ch - 'Z' + 'A' - 1;
            }
            text[i] = (char)ch;
        }
    }
    printf("The encrypted text is: %s",text);
    return 0;
}