C 什么';“第二个”的意思是什么;如果;声明(凯撒密码)

C 什么';“第二个”的意思是什么;如果;声明(凯撒密码),c,encryption,C,Encryption,我最近对加密感兴趣,然后我遇到了这段代码,但我不理解第二个“IF”语句的含义 #include<stdio.h> int main() { char message[100], ch; int i, key; printf("Enter a message to encrypt: "); gets(message); printf("Enter key: "); scanf("%d&

我最近对加密感兴趣,然后我遇到了这段代码,但我不理解第二个“IF”语句的含义

#include<stdio.h>

int main()
{
    char message[100], ch;
    int i, key;

    printf("Enter a message to encrypt: ");
    gets(message);
    printf("Enter key: ");
    scanf("%d", &key);

    for (i = 0; message[i] != '\0'; ++i) {
        ch = message[i];

        if (ch >= 'A' && ch <= 'Z') {
            ch = ch + key;

            if (ch > 'Z') {
                ch = ch - 'Z' + 'A' - 1;
            }
            
            message[i] = ch;
        }
    }

    printf("Encrypted message: %s", message);

    return 0;
}
#包括
int main()
{
char消息[100],ch;
int i,键;
printf(“输入要加密的消息:”);
获取(消息);
printf(“输入键:”);
scanf(“%d”和键)(&key);
对于(i=0;消息[i]!='\0';++i){
ch=消息[i];
如果(ch>='A'&&ch'Z'){
ch=ch-'Z'+'A'-1;
}
消息[i]=ch;
}
}
printf(“加密消息:%s”,消息);
返回0;
}

要理解该代码的意义,最基本的一点是
char
同时表示字符和数字

这是因为对于C程序(实际上所有计算机上的所有程序)而言,字符只是数字

当你说
'A'
时,你可以等效地使用
65
0x41
*

通过将
key
添加到
ch
以“上移”字符(即,如果
key
为1,则
'A'
变为
'B'
),您已经使用了该属性

但是,如果将1添加到
'Z'
,则结果不再是大写字符(它将是ASCII和兼容编码中的
[

第二个if负责通过首先减去
'Z'
(这意味着现在的值是“我们比Z高多少步),然后添加
'A'-1
(这意味着比
'Z
高1步将导致
'A


*假设这是使用或兼容的编码,这在大多数现代操作系统上都适用

要理解该代码的意义,最基本的一点是,
char
同时表示字符和数字

这是因为对于C程序(实际上所有计算机上的所有程序)而言,字符只是数字

当你说
'A'
时,你可以等效地使用
65
0x41
*

通过将
key
添加到
ch
以“上移”字符(即,如果
key
为1,则
'A'
变为
'B'
),您已经使用了该属性

但是,如果将1添加到
'Z'
,则结果不再是大写字符(它将是ASCII和兼容编码中的
[

第二个if负责通过首先减去
'Z'
(这意味着现在的值是“我们比Z高多少步),然后添加
'A'-1
(这意味着比
'Z
高1步将导致
'A


*假设这是使用或兼容的编码,这在大多数现代操作系统上都是正确的

让我们重写在
if
语句的表达式为
true
时执行的计算:

ch = ch - 'Z' + 'A' - 1;

这应该更有意义。现在括号之间的部分当然不会改变值,所以让我们引入一个常量:

#define APHABET_SIZE = ('Z' - 'A' + 1)
...
ch = ch - ALPHABET_SIZE;
啊,如果字符的值大于字母表中最后一个字母Z,那么减去字母表的大小


这是一种您不应该自己执行的编程;它一次执行所有功能,而不是将其分解,并以简洁性换取可读性


凯撒密码执行模加运算以按索引移动字符。您应该使用函数
int charToIndex(char)
,然后使用
%
模运算符和
字母表大小
,执行模加(或减法)解密,然后使用函数
char indexToChar(int)
将其转换回。

如果
if
语句的表达式为
true,则重写执行的计算:

ch = ch - 'Z' + 'A' - 1;

这应该更有意义。现在括号之间的部分当然不会改变值,所以让我们引入一个常量:

#define APHABET_SIZE = ('Z' - 'A' + 1)
...
ch = ch - ALPHABET_SIZE;
啊,如果字符的值大于字母表中最后一个字母Z,那么减去字母表的大小


这是一种您不应该自己执行的编程;它一次执行所有功能,而不是将其分解,并以简洁性换取可读性


凯撒密码执行模加运算以按索引移动字符。您应该使用函数
int charToIndex(char)
,然后使用
%
模运算符和
字母表大小
,执行模加(或减法)解密,然后使用函数
char indexToChar(int)
将其转换回。

它将
ch
重新调整到A..Z范围内,请注意此代码不可移植,请使用
if(isupper((unsigned)ch)){
而不是
if(ch>='A'&&ch@DavidRanieri:仅此修复无法使此代码普遍适用于所有编码,因此我不会为此烦恼。@JoachimSauer哪种修复最好?@EmmanuelManoloSiame:根本问题是编码变得比ASCII复杂得多,将此代码修复为所有编码将使其成为一个版本与我假设的不同的是,学习C和文本的一个简单练习。我认为这几乎与这个问题完全无关。基本上,整个概念都是“将字符n提升”如果你考虑整个Unicode空间,或者说得直截了当,那就变得怪异:就像凯撒密码几乎完全是一个学习工具和加密的历史例子一样,把字符当作数字,你可以增加和减量得到。