c++ - 维吉尼亚密码

标签 c++ encryption vigenere

我将如何修改此代码以接受来自用户的输入而不是使用预先确定的字符串?具体来说,我需要程序恰好需要两个命令行参数。第一个将是代码“-e”或“-d”以指示消息的编码或解码(这决定了添加或减去您的移位值),第二个参数将是一个单词,它将是您要输入的关键字用于加密或解密。

#include <iostream>
#include <cstring>
#include <algorithm>

// Vigenere Cipher Methods:
// Note: assumes that both strings as arguments have length > 0, and that
//       the key only contains letters of the alphabet from [A-Z]

void vigenere_encrypt(std::string& s, std::string key)
{
    std::transform(s.begin(), s.end(), s.begin(), ::toupper);
    std::transform(key.begin(), key.end(), key.begin(), ::toupper);
    unsigned int j = 0;
    for (int i = 0; i < s.length(); i++)
    {
        if (isalpha(s[i]))
        {
            s[i] += key[j] - 'A';
            if (s[i] > 'Z') s[i] += -'Z' + 'A' - 1;
        }
        j = j + 1 == key.length() ? 0 : j + 1;
    }
}

void vigenere_decrypt(std::string& s, std::string key)
{
    std::transform(s.begin(), s.end(), s.begin(), ::toupper);
    std::transform(key.begin(), key.end(), key.begin(), ::toupper);
    unsigned int j = 0;
    for (int i = 0; i < s.length(); i++)
    {
        if (isalpha(s[i]))
        {
            s[i] = s[i] >= key[j] ?
                s[i] - key[j] + 'A' :
                'A' + ('Z' - key[j] + s[i] - 'A') + 1;
        }
        j = j + 1 == key.length() ? 0 : j + 1;
    }
}

int main(void)
{
    std::string s("AceInfinity's Example");
    std::string key("Passkey");
    vigenere_encrypt(s, key);
    std::cout << "Encrypted: " << s << std::endl;
    vigenere_decrypt(s, key);
    std::cout << "Decrypted: " << s << std::endl;
    return 0;
}

更新

感谢您的输入和其他一些资源,我重新开发了我的主要代码,如下所示。我无法让程序正确解密和加密字符串,我不确定错误是代码本身的某个地方,还是运算符(operator)错误。这里有什么地方看起来不正常吗?我怎样才能使这段代码发挥作用,使其能够加密或解密给定的用户输入?

#include <iostream>
#include <string>

int usage( const char* exe_name )
{
    std::cerr << "Usage: " << exe_name << " -e <text to encrypt>\n"
              << "       " << exe_name << " -d <text to decrypt>\n" ;
    return 1 ;
}

int main( int argc, char* argv[] )
{
    if (argc < 3 ) return usage( argv[0] ) ;

    const std::string option = argv[1];

    std::string text = argv[2];
    // cat the remaining cmd line args
    for( int i = 3 ; i < argc ; ++i ) { text += ' ' ; text += argv[i] ; }

    const std::string key("Passkey");

    if ( option== "-e" )
        std::cout << "Encrypt: '" << text << "'\n" ;

    else if ( option == "-d" )
        std::cout << "Decrypt: '" << text << "'\n" ;

    else
    {
        std::cout << "Unrecognised command line option '" << option << "'\n";
        return usage( argv[0] ) ;
    }
}

最佳答案

如果您需要命令行参数,您需要稍微更改主函数的原型(prototype)并使用标准的 argv 数组:

int main(int argc, const char** argv)
{
    std::string s("AceInfinity's Example");

    if (argc != 3)
    {
        std::cout << "Usage: -e text\n" << "       -d text\n";
        return 0;
    }

    std::string arg1 = argv[1];
    std::string arg2 = argv[2];

    if (arg1 == "-e")
    {
        vigenere_encrypt(s, arg2);
        std::cout << "Encrypted: " << s << std::endl;
    }
    else if (arg1 == "-d")
    {
        vigenere_decrypt(s, arg2);
        std::cout << "Decrypted: " << s << std::endl;
    }
    else
        std::cout << "Unrecognised command line option " << arg1 << "\n";

    return 0;
}

为快速示例所做的最小努力,代码可能有效,e&oe,买者自负等。

当然,您真的最好使用适当的命令行参数解析器,例如getopt。 ,并且您仍然需要一些方法来提供用于加密的明文或用于解密的密文,但这留给读者作为练习。例如,通过使用 std::cinstdin 读取是一种方法。

关于c++ - 维吉尼亚密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26989291/

相关文章:

c - 在 1d 数组中写入 vigenere 正方形

c - Vigenere CS50 - 需要帮助循环浏览字母

c++ - C++1z 范围的状态?

c++ - 将动态 C 运行时链接到 clang (windows)

Swift如何导入rsa key

encryption - AES 输出 block 大小

node.js - 无法解密 NodeJS 中使用 Swift CryptoKit 加密的数据 - AES-256-GCM

c# - 如何使用后期绑定(bind)调用 native C 库?

c++ - 如何确定哪个小部件触发了插槽功能?

CS50 维吉尼亚密码给出错误的输出