Vigenere的C密码(CS50)

时间:2015-09-07 14:25:00

标签: c vigenere cs50

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

我基本上让它工作它只会允许正确的字符,如果关键字的长度与消息的长度相同,那么就是好的。

我遇到的问题是在邮件加密时找到重置关键字循环的方法,因此如果我输入关键字“A'和消息'这是一个测试'加密的邮件应该是'这是一个测试'因为' A'值得在ASCII表中零移位。

#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;
      }

1 个答案:

答案 0 :(得分:2)

首先,您应该启用更多编译器警告。例如,使用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]
 }
 ^

所有这些都应该修复:

  • return 0
  • 末尾添加alphaCheck
  • 删除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;
    }
}