Vigenere 密码逻辑错误
Vigenere Cipher logic error
#include<stdio.h>
#include<cs50.h>
#include<ctype.h>
#include<string.h>
int main(int argc, string argv[]){
int k,j,i=0,ch,pos;
bool apha=true;
string in = GetString();
int num = strlen(in);
for(int z=0;z<strlen(argv[1]);z++){
if(!isalpha(argv[1][z])){
apha=false;
}
}
if(argc!=2||!apha){
printf("Dude we only accept alphabets...");
return 1;
}
string key = argv[1];
int keylength = strlen(key);
for (i=0,j=0;i<num;i++,j++){
if(isupper(key[i])){
k=key[j%keylength]-'A';
}
if(islower(key[i])){
k=key[j%keylength]-'a';
}
if(isupper(in[i])){
pos=in[i]-'A';
ch = ((pos + k)%26) + 'A';
printf("%c",ch);
}
if(islower(in[i])){
pos=in[i]-'a';
ch = ((pos + k)%26) + 'a';
printf("%c",ch);
}
if(isspace(in[i])){
printf(" ");
}
if(ispunct(in[i])){
printf("%c",in[i]);
}
}
printf("\n");
}
输出条件检查:
:) vigenere.c 存在
:) vigenere.c编译
:) 使用 "a" 作为关键字
将 "a" 加密为 "a"
:( 使用 "baz" 作为关键字将 "world, say hello!" 加密为 "xoqmd, rby gflkp!"
\ 预期输出,但不是 "xoqkj, yfd gfllp!\n"
:( 使用 "BaZ" 作为关键字将 "BaRFoo" 加密为 "CaQGon"
\ 预期输出,但不是 "CaQEun\n"
:( 使用 "BAZ" 作为关键字将 "BARFOO" 加密为 "CAQGON"
\ 预期输出,但不是 "CAQEON\n"
:( 处理缺少 argv[1]
\ 预期输出,而不是输入提示
:( 处理 argc > 2
\ 预期输出,而不是输入提示
:( 拒绝将 "Hax0r2" 作为关键字
\ 预期输出,而不是输入提示
我的代码有什么问题?我仔细检查了逻辑,错误似乎出在密钥的包装方式上,尽管我找不到任何错误。我哪里做错了?
你的代码有几个问题:
你的错误检查不正确。在评估 strlen(argv[1])
之后检查 if(argc!=2||!apha)
—— 到那时就太晚了!在访问 argv
之前检查 argc
的有效性并且不要将参数计数错误和字母键错误加倍,它们是独立的。此外,错误消息应转到 stderr
,而不是 stdout
。
您完全错误地处理了键索引。正如@Bob__ 指出的,此代码中的索引:
if(isupper(key[i])){
k=key[j%keylength]-'A';
}
需要保持一致
if (isupper(key[j % keylength])) {
k = key[j % keylength] - 'A';
}
而且,你没有正确增加 j
,你让它跟踪 i
:
for (i=0,j=0;i<num;i++,j++){
相反,i
应该为输入字符串中的每个字符递增,j
应该为输入字符串中的每个可加密字母递增。
修改您的代码以修复上述错误和一般样式问题,我们得到如下内容:
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[]) {
if (argc != 2) {
fprintf(stderr, "Please supply an encryption key.\n");
return 1;
}
string key = argv[1];
int key_length = strlen(key);
bool is_alpha = true;
for (int z = 0; z < key_length; z++) {
if (!isalpha(key[z])) {
is_alpha = false;
}
}
if (!is_alpha) {
fprintf(stderr, "Sorry, we only accept alphabetic keys.\n");
return 1;
}
string in = GetString();
size_t length = strlen(in);
for (int i = 0, j = 0; i < length; i++) {
if (isalpha(in[i])) {
int ch, k = key[j++ % key_length];
if (isupper(k)) {
k -= 'A';
} else {
k -= 'a';
}
if (isupper(in[i])) {
int pos = in[i] - 'A';
ch = ((pos + k) % 26) + 'A';
} else {
int pos = in[i] - 'a';
ch = ((pos + k) % 26) + 'a';
}
printf("%c", ch);
} else if (isspace(in[i])) {
printf(" ");
} else if (ispunct(in[i])) {
printf("%c", in[i]);
}
}
printf("\n");
return 0;
}
使用模拟
> ./a.out baz
world, say hello!
xoqmd, rby gflkp!
>
这是我得到的答案-
-最明显的错误可能是:
if(isupper(key[i])){
k=key[j%keylength]-'A';
}
它应该检查相应的字符,所以应该检查:
if (isupper(key[j % keylength])) {
k = key[j % keylength] - 'A';
}
-此外,键增量的增量很重要,只有当它是字母时才增量。因此需要对此进行 isalpha 检查(因为即使 space,您也不希望字符发生变化)。
#include<stdio.h>
#include<cs50.h>
#include<ctype.h>
#include<string.h>
int main(int argc, string argv[]){
int k,j,i=0,ch,pos;
bool apha=true;
string in = GetString();
int num = strlen(in);
for(int z=0;z<strlen(argv[1]);z++){
if(!isalpha(argv[1][z])){
apha=false;
}
}
if(argc!=2||!apha){
printf("Dude we only accept alphabets...");
return 1;
}
string key = argv[1];
int keylength = strlen(key);
for (i=0,j=0;i<num;i++,j++){
if(isupper(key[i])){
k=key[j%keylength]-'A';
}
if(islower(key[i])){
k=key[j%keylength]-'a';
}
if(isupper(in[i])){
pos=in[i]-'A';
ch = ((pos + k)%26) + 'A';
printf("%c",ch);
}
if(islower(in[i])){
pos=in[i]-'a';
ch = ((pos + k)%26) + 'a';
printf("%c",ch);
}
if(isspace(in[i])){
printf(" ");
}
if(ispunct(in[i])){
printf("%c",in[i]);
}
}
printf("\n");
}
输出条件检查: :) vigenere.c 存在
:) vigenere.c编译
:) 使用 "a" 作为关键字
将 "a" 加密为 "a":( 使用 "baz" 作为关键字将 "world, say hello!" 加密为 "xoqmd, rby gflkp!"
\ 预期输出,但不是 "xoqkj, yfd gfllp!\n"
:( 使用 "BaZ" 作为关键字将 "BaRFoo" 加密为 "CaQGon"
\ 预期输出,但不是 "CaQEun\n"
:( 使用 "BAZ" 作为关键字将 "BARFOO" 加密为 "CAQGON"
\ 预期输出,但不是 "CAQEON\n"
:( 处理缺少 argv[1]
\ 预期输出,而不是输入提示
:( 处理 argc > 2
\ 预期输出,而不是输入提示
:( 拒绝将 "Hax0r2" 作为关键字
\ 预期输出,而不是输入提示
我的代码有什么问题?我仔细检查了逻辑,错误似乎出在密钥的包装方式上,尽管我找不到任何错误。我哪里做错了?
你的代码有几个问题:
你的错误检查不正确。在评估 strlen(argv[1])
之后检查 if(argc!=2||!apha)
—— 到那时就太晚了!在访问 argv
之前检查 argc
的有效性并且不要将参数计数错误和字母键错误加倍,它们是独立的。此外,错误消息应转到 stderr
,而不是 stdout
。
您完全错误地处理了键索引。正如@Bob__ 指出的,此代码中的索引:
if(isupper(key[i])){
k=key[j%keylength]-'A';
}
需要保持一致
if (isupper(key[j % keylength])) {
k = key[j % keylength] - 'A';
}
而且,你没有正确增加 j
,你让它跟踪 i
:
for (i=0,j=0;i<num;i++,j++){
相反,i
应该为输入字符串中的每个字符递增,j
应该为输入字符串中的每个可加密字母递增。
修改您的代码以修复上述错误和一般样式问题,我们得到如下内容:
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[]) {
if (argc != 2) {
fprintf(stderr, "Please supply an encryption key.\n");
return 1;
}
string key = argv[1];
int key_length = strlen(key);
bool is_alpha = true;
for (int z = 0; z < key_length; z++) {
if (!isalpha(key[z])) {
is_alpha = false;
}
}
if (!is_alpha) {
fprintf(stderr, "Sorry, we only accept alphabetic keys.\n");
return 1;
}
string in = GetString();
size_t length = strlen(in);
for (int i = 0, j = 0; i < length; i++) {
if (isalpha(in[i])) {
int ch, k = key[j++ % key_length];
if (isupper(k)) {
k -= 'A';
} else {
k -= 'a';
}
if (isupper(in[i])) {
int pos = in[i] - 'A';
ch = ((pos + k) % 26) + 'A';
} else {
int pos = in[i] - 'a';
ch = ((pos + k) % 26) + 'a';
}
printf("%c", ch);
} else if (isspace(in[i])) {
printf(" ");
} else if (ispunct(in[i])) {
printf("%c", in[i]);
}
}
printf("\n");
return 0;
}
使用模拟
> ./a.out baz
world, say hello!
xoqmd, rby gflkp!
>
这是我得到的答案-
-最明显的错误可能是:
if(isupper(key[i])){
k=key[j%keylength]-'A';
}
它应该检查相应的字符,所以应该检查:
if (isupper(key[j % keylength])) {
k = key[j % keylength] - 'A';
}
-此外,键增量的增量很重要,只有当它是字母时才增量。因此需要对此进行 isalpha 检查(因为即使 space,您也不希望字符发生变化)。