维吉尼亚密码

Posted

技术标签:

【中文标题】维吉尼亚密码【英文标题】:Vigenère Cipher code 【发布时间】:2014-11-18 08:00:40 【问题描述】:

我将如何修改此代码以接受来自用户的输入,而不是使用预先确定的字符串?具体来说,我需要程序恰好需要两个命令行参数。第一个将是代码“-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;


更新

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

#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] ) ;
    

【问题讨论】:

你到底尝试了什么?那时发生了什么?它与您的预期有何不同? 当前代码只包含一个固定字符串来解码。我需要代码来接受输入,指示加密或解密。问题是我是 C++ 的新手,知识非常有限。我将按照下面的建议实现解析,但不确定如何根据标志(-e 用于加密或 -d 用于解密)将解析的输入发送到加密或解密状态。您能否就如何进行提供任何建议? 修改后的代码的问题在于,您从未调用过vigenere_encrypt()vigenere_decrypt() 函数。您也不再需要key,因为您的text 包含密钥。或者您只需将变量 text 重命名为 key 这开始朝着代码审查的方向发展,因为此时您似乎没有任何具体问题。 【参考方案1】:

如果你想要命令行参数,你需要稍微改变你的主函数的原型并使用标准的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::cin 读取stdin 是一种方法。

【讨论】:

解析在这里非常有意义,之前没有想到它,因为我根本不知道那个函数(我是 C++ 的新手)。至于提供用于加密或解密的文本,我会根据标志将解析后的术语从 main 发送到任一函数吗?解决这个问题的最好方法是什么?这是我编程知识的边缘 @kdg926:这开始偏离主题了。但是接下来看哪里的简短回答:您可以按照我的建议从标准输入读取文本,您可以通过解析 -f 或其他任何内容的参数从文件中读取文本,并且您可以通过重写加密很容易地将两者结合起来/decryption 例程以使用流(请参阅***.com/questions/23050273/… 以帮助您入门)。但是,当您遇到特定困难时,应该真正尝试一些东西并提出新问题。【参考方案2】:

使用cin 接受来自用户的输入并将其输入到字符串中。解析字符串以获得 -e/-d 标志和关键字。如果输入不是你想要的,提示用户再试一次。

【讨论】:

这似乎不符合“命令行参数”的要求。

以上是关于维吉尼亚密码的主要内容,如果未能解决你的问题,请参考以下文章

密码那些事儿|(十)“钥匙”打开维吉尼亚的锁

维吉尼亚密码(Vigenère cipher)

维吉尼亚密码:加密强悍,却为何没人用?

《密码学》维吉尼亚密码。

凯撒简单替换维吉尼亚密码 CRC 破解

维吉尼亚密码 C++