我一直在处理问题集的Caesar密码问题,但我遇到了一个小问题。 每当密码值越来越大于' z'的ascii时,我希望它能够反弹到' a'但我无法弄清楚如何做到这一点。 这是代码:
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, string argv[])
{
if(argc !=2 && !isdigit(argv[1]))
{
return 1;
}
//convert input to int and get the string
int k = atoi(argv[1]);
k=k%26;
//printf("%d" ,k);
//get he text
char *s;
s=GetString();
int i, n=strlen(s);
//checking each character
for(i=0;i<n;i++)
{
if(s[i]==' ')
{
s[i]=' ';
}
else
{
s[i]=s[i]+k;
}
printf("%c" ,s[i]);
}
}
这是一个非常基本的代码。任何帮助将不胜感激。
P.S。这是一个关键4的例子。
input- Vinay Dawani
output- Zmre} He{erm
答案 0 :(得分:0)
假设使用的代码集不是EBCDIC(字母字符之间有非字母字符),那么拉丁字母(unaccented az)的字母被编码为所有常见字母中的连续代码点代码集。当你知道如何时,字母表的旋转很简单。
从根本上说,您将每个字母转换为字母a
或A
的偏移0..25(取决于大小写),添加编码密钥,取结果模26,然后添加首字母(a
或A
)返回。请注意,算法发生在int
,但结果会被分配回(可能已签名)char
。
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, string argv[])
{
if (argc != 2 || !isdigit((unsigned char)argv[1][0]))
{
fprintf(stderr, "Usage: %s shift\n", argv[0]);
return 1;
}
// convert input to int and get the string
int k = atoi(argv[1]) % 26;
if (k < 0)
k += 26;
char *s = GetString();
int n = strlen(s);
printf("Original: [%s]\n", s);
// encoding each character
for (int i = 0; i < n; i++)
{
if (isupper((unsigned char)s[i]))
{
s[i] = 'A' + (s[i] - 'A' + k) % 26;
}
else if (islower((unsigned char)s[i]))
{
s[i] = 'a' + (s[i] - 'a' + k) % 26;
}
}
printf("Encrypted: [%s]\n", s);
return 0;
}
示例运行:
$ ./caesar13 3
Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it?
Original: [Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it?]
Encrypted: [Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw?]
$ ./caesar50 23
Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw?
Original: [Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw?]
Encrypted: [Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it?]
$
CS50 library随时可在线获取。
答案 1 :(得分:-1)
在信中添加k
后,请检查它是否高于z
。如果是,只需减去字母表中的字母数量即可将其包裹起来。
s[i] = s[i]+k;
if (s[i] > 'z') {
s[i] = s[i] - 26;
}
要处理大写和小写,你需要在主循环中进行单独的测试。
for(i=0;i<n;i++)
{
if(islower(s[i]))
{
s[i] += k;
if (s[i] > 'z') {
s[i] -= 26;
}
}
else if (isupper(s[i]))
{
s[i] += k;
if (s[i] > 'Z') {
s[i] -= 26;
}
}
printf("%c" ,s[i]);
}
请注意,我删除了if (s[i] == ' ')
的测试。这不是必要的 - 任何不是一封信的东西都是孤零零的。