1

我正在为我的实验表制作凯撒密码,并使其能够加密 3 个替代密码(凯撒密码),这是练习的重点。但是有一件事困扰着我。首先,如果我把它放在 3 以外的地方,就会有一个尾随字符。例如,输入“恶意软件”,然后输入 2 作为密钥。这是我的代码:

#include<stdio.h>
#include<stdlib.h>

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

   printf("Please enter a word/sentence (lowercaps) for encrypting :\n ");
   fgets(text,100,stdin);
   printf("Please enter the key that you desire : eg:14\n");
   scanf("%d", &key);
   for(i=0;i<strlen(text);i++)
   {
      if (key>=26)
      {
         key=key%26;
      }
      if (text[i]==' ')
      {
         continue;
      }
      if(text[i]+key>'z')
      {
         text[i]-=97;
         text[i]+=26;
         text[i]+=key;
         text[i]%=26;
         text[i]+=97;
      }
      else
      {
         text[i]=text[i]+key;
      }
   }

   printf("this is your encrypted text : %s", text );
}

我希望我遵循正确的缩进方法进行编码。也因此被很多人嫌弃

4

3 回答 3

2

代码是 1) 未正确检测 a 何时char是小写字母 2) 加密非字母,包括'\n'导致fgets()OP 的“我的输出的最后一个字符之后的尾随字符”。

反而:

if (text[i] >= 'a' && text[i]<= 'z') {
   text[i] = (text[i] - 'a' + key)%26 + `a`;
}
else {
  ; // nothing 
}

或者

if (islower((unsigned char) text[i]) {
   text[i] = (text[i] - 'a' + key)%26 + `a`;
}

注意:以上依赖char都被编码为ASCII

一种不依赖于 ASCII 的解决方案。

static const char lowercase[] = "abcdefghijklmnopqrstuvwxyz";
char *p = strchr(lowercase, text[i]);
if (p) {
  int offset = (p - lowercase + key)%26;
  text[i] = lowercase[offset];
}
于 2015-09-24T05:46:52.793 回答
0

我将简化并更正此代码以

#include <stdio.h>

int main() {
    char text[100];
    int key, i;
    printf("Enter a word / sentence (lowercaps) for encrypting : ");
    fgets(text, 100, stdin);
    printf("Enter the key that you desire (eg. 14) : ");
    scanf("%d", &key);
    key %= 26;    // Pull this out of the loop and remove the unnecessary if
    for (i = 0; text[i]; ++i) {    // Correct the loop condition
        if (text[i] == ' ') continue;
        if (text[i] + key > 'z')
            text[i] = (text[i] - 97 + 26) % 26 + 97;    // Simplify
        else
            text[i] += key;
    }
    printf("Encrypted text : %s\n", text);
    return 0;
}

输入

Enter a word / sentence (lowercaps) for encrypting : malware
Enter the key that you desire (eg. 14) : 2

输出

Encrypted text : ocnyctg
于 2015-09-24T05:21:19.703 回答
0

正如 Blake_Lead 所说,这个 '\0' 字符在你的密码中被改变了

事实上,我对缓冲区的长度是错误的,因为 fgets()
从手册页中放置了一个 '\0':

终止的空字节 ('\0') 存储在缓冲区中的最后一个字符之后。

所以,你只需要改变你的测试

if (text[i]==' ')

通过类似的东西:

 if (text[i] < 'A' || text[i] > 'z' || (text[i] > 'Z' && text[i] < 'a') )
于 2015-09-24T05:03:24.870 回答