C 中的 Vigenere 密码 (CS50)

Vigenere's Cipher in C (CS50)

我已经坚持了一段时间了,我以为我让它工作了好几次只是为了找到更多我忘记的东西。基本上问题集是使用C创建Vigenere Cipher,规则可以找到here

我基本上让它工作了,它只允许正确的字符,如果关键字与消息的长度相同,一切都很好。

我遇到的问题是想办法在消息被加密时重置关键字的循环,所以如果我输入关键字 'A' 和消息 'This is a test' 加密消息应该读作 'This is a test',因为 'A' 值得沿 ASCII table.

移动零
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>

int main(int argc, char * keyWord[]) {
  int cipher[64], i, j, k, l;
  char message[128];

  // Validation - using alphaCheck Function
  if (argc != 2 || alphaCheck(keyWord) == 2) {
    return 1;
  }

  // For loop to convert to upper and set value ie A = 0 B = 1
  for (i = 0, j = strlen(keyWord[1]); i < j; i++) {
    cipher[i] = (toupper(keyWord[1][i]) - 65);
    printf("%i\n", cipher[i]);
  }

  // Prompt the user for the message to encrypt
  printf("Enter your secret message: ");
  fgets(message, 128, stdin);


  int keyCount = 0;
  int p = strlen(keyWord[1]);

  if (keyCount < p) {
    keyCount++;
  } else {
    keyCount = 0;
  }

  for (i = 0, k = strlen(message); i < k; i++) {
    if (isspace(message[i])) {
      printf(" ");
    } else if (isupper(message[i])) {
        char c = (message[i] - 65 + cipher[i])  % 26 + 65;
        printf("%c", c);
      }
      else {
        char d = (message[i] - 97 + cipher[i]) % 26 + 97;
        printf("%c", d);
      }
  }
}



// Function to check if alphabet characters.
int alphaCheck(char * argv[]) {
  int length = strlen(argv[1]), n;
  for (n = 0; n < length; n++) {
    if (!isalpha(argv[1][n])) {
      printf("Characters 'A-Z' for Keyword.\n");
      return 2;
    }
  }
}

以下部分在我留下来展示我如何尝试解决问题但失败时是多余的。

int keyCount = 0;
      int p = strlen(keyWord[1]);

      if (keyCount < p) {
        keyCount++;
      } else {
        keyCount = 0;
      }

首先,您应该启用更多编译器警告。例如,使用 gcc 和我最喜欢的一组标志 (-pedantic -Wall -Wextra -Wundef -Wendif-labels -Wshadow -Wbad-function-cast -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wdisabled-optimization -O2) 我得到:

$ cc prog.c
prog.c: In function ‘main’:
prog.c:12:20: warning: implicit declaration of function ‘alphaCheck’ [-Wimplicit-function-declaration]
   if (argc != 2 || alphaCheck(keyWord) == 2) {
                    ^
prog.c:12:3: warning: nested extern declaration of ‘alphaCheck’ [-Wnested-externs]
   if (argc != 2 || alphaCheck(keyWord) == 2) {
   ^
prog.c:8:28: warning: unused variable ‘l’ [-Wunused-variable]
   int cipher[64], i, j, k, l;
                            ^
prog.c: At top level:
prog.c:53:5: warning: no previous prototype for ‘alphaCheck’ [-Wmissing-prototypes]
 int alphaCheck(char * argv[]) {
     ^
prog.c: In function ‘alphaCheck’:
prog.c:61:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

所有这些都应该修复:

  • alphaCheck
  • 末尾添加return 0
  • 移除l
  • int alphaCheck(char *[]);放在main之前(或者将整个函数移到main之前,使其成为static

你的主循环有三种情况。它检查空格、大写字符,其他所有字符均假定为小写字符。您应该检查大写字母、小写字母,并通过不变的方式传递其他所有内容(例如标点符号 .,):

if (isupper(message[i])) {
    ...
} else if (islower(message[i])) {
    ...
} else {
    printf("%c", message[i]);
}

你对 keyCount 的想法不错,但它需要与主循环集成。也就是说,你应该在循环中使用cipher[keyCount],而不是cipher[i],并且每次这样使用它时都会增加keyCount

然后,在每次迭代结束时,您可以检查是否 运行 失调(并重置 keyCount):

for ( ... ) {
    ...

    if (keyCount >= p) {
        keyCount = 0;
    }
}