c - 字符串中的大写字符无法转换为小写字符,并且减去它们的 ASCII 值不会使它们出现在字母索引中

标签 c encryption cs50 vigenere

我是一名尝试学习编码的初学者。 目前我正在学习CS50类(class)。我遇到了维吉尼亚密码问题;请在下面的 github 链接上查看我的代码。

#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ASCII_VALUE_LOWER 97
#define ASCII_VALUE_UPPER 65
#define NR_OF_LETTERS 26

int main(int argc, string argv[])
{
    char key[strlen(argv[1]) + 1];
    strcpy(key, argv[1]);
    int keyLen = strlen(key);

    for (int k = 0; k < keyLen; k++)
    {
        if (!isalpha(key[k]))
        {
            printf("ERROR: Secret key has to be alphabetical string, program will be terminated now!\n");
            return 1; // main should return 1 (signify an error)
        }
        //converting key letters to respective values
        if (isupper(key[k]))
            {
                key[k] -= ASCII_VALUE_UPPER;
            }
            key[k] -= ASCII_VALUE_LOWER;
    }
    //if program is executed without an argument, or with more than one arguments
    if (argc != 2)
    {
        printf("ERROR: You need to give a secret key as an argument, program will be terminated now!\n");
        return 1; // main should return 1 (signify an error)
    }
    else
    {
        string plaintext = get_string("plaintext: "); //get a plaintext from a user using cs50 custom function from their library
        int stringLen = strlen(plaintext);
        int keyIndex = 0;

        for (int j = 0; j < keyLen; j++)
        {

        }

        //for each character in the plaintext string
        for (int i = 0; i < stringLen; i++)
        {
            //check if is alphabetic (tolower, toupper)
            if (isalpha(plaintext[i]))
            {
                //cypher_character = (plain_character + key_character)% 26
                if (islower(plaintext[i]))
                {
                    keyIndex %= keyLen;
                    plaintext[i] = ((plaintext[i] - ASCII_VALUE_LOWER + key[keyIndex]) % NR_OF_LETTERS) + ASCII_VALUE_LOWER;
                }
                else
                {
                    plaintext[i] = ((plaintext[i] - ASCII_VALUE_UPPER + key[keyIndex]) % NR_OF_LETTERS) + ASCII_VALUE_UPPER;
                }
                keyIndex++;
            }
            //else leave as is
        }

        //print ciphertext in a format "ciphertext: " + ciper
        printf("ciphertext: %s\n", plaintext);
        return 0;
    }
}

问题如下:

  1. 如果您在键中传递大写字母的参数,则值会很奇怪并且转换不起作用。这个想法是取字符串 key 中的每个字符,如果大写则减去 65,如果小写则减去 97,因此它们的 ASCII 值将变为 0 - 25。然后我可以在 Vigenere 密码公式中使用它们: 密码[i_index] = (明文[i_index] + key[j_index]) % 26

  2. 不处理缺少argv[1]的情况,即使存在 IF 条件(!argc == 2),所以它应该'如果你没有通过任何东西,就不会通过。

    "failed to execute program due to segmentation fault".
    

我已经尽力了,我很累,也许明天解决方案就会立即弹出。 我请你给我一些提示,可能不会透露所有内容,但也许会指导我,这样我就可以从中学习。

最佳答案

    if (isupper(key[k]))
        {
            key[k] -= ASCII_VALUE_UPPER;
        }
        key[k] -= ASCII_VALUE_LOWER;

如果字符为大写,则会减去 ASCII_VALUE_UPPER。然后,无论如何,它都会减去 ASCII_VALUE_LOWER。从周围的代码来看,我假设您的意思是:

    if (isupper(key[k])) {
        key[k] -= ASCII_VALUE_UPPER;
    } else {
        key[k] -= ASCII_VALUE_LOWER;
    }

关于c - 字符串中的大写字符无法转换为小写字符,并且减去它们的 ASCII 值不会使它们出现在字母索引中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52019891/

相关文章:

比较 2 个数组中的值

具有固定/预分配寄存器的表达式的代码生成

encryption - 如何手动计算和验证证书签名请求的签名

c - 如何在For循环中输入两个条件?

sqlite - SQLite从联接表执行查询

c - gcc编译器错误: "cannot find -lcs50 collect2: Id returned 1 exit status"

c - 使用 Windows MIDI API 时出现问题(播放时没有回调)

C编程gdb报错信息

web-services - 通过 HTTPS 发送的密码加密

java - 如果我将加密的 html 文件解析为字符串,我可以以某种方式从中获取文本吗?