c++ Vigenere 密码

Vigenere 密码简介

        维吉尼亚密码(Vigenere cipher)是一种古老的替代密码算法,由法国密码学家布拉斯·维吉尼亚(Blaise de Vigenère)在16世纪末提出。

        该密码算法是一种多字母替代密码,使用一个关键字来对明文进行加密。每个字母都根据关键字中的对应字母来确定一个位移量,然后将明文中的字母加上该位移量,得到密文中的字母。加密和解密过程是对称的,解密时只要将密文中的字母减去位移量即可还原为明文字母。

维吉尼亚密码算法的具体过程如下:

  1. 选定一个关键字(例如:"LEMON")。
  2. 将明文中的字母逐个与关键字中的字母对应相加(顺序重复使用关键字中的字母),得到对应的密文字母。
  3. 如果明文字母为非字母字符,则保持原样不加密。
  4. 解密时,使用相同的关键字和位移量,将密文中的字母逐个减去位移量得到明文字母。
  5. 使用相同的关键字和位移量加密和解密数据,可以得到正确的结果。

        维吉尼亚密码相对于凯撒密码(Caesar cipher)等单字母替代密码来说更加复杂,因为它使用了一个关键字来确定位移量,并且对于相同的明文可以产生不同的密文。

        然而,维吉尼亚密码在现代密码学中已经不再被视为安全的加密算法,因为它很容易受到频率分析等攻击。因此,在真实的应用中,我们通常会使用更强大和更复杂的加密算法,如AES(Advanced Encryption Standard)或RSA(Rivest-Shamir-Adleman)。

示例一:

/**
 * @file vigenere_cipher.cpp
 * @brief Implementation of [Vigenère cipher](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher) algorithm.
 *
 * @details
 * The Vigenère cipher is a method of encrypting alphabetic text by using a series of interwoven vigenere 
 * ciphers, based on the letters of a keyword. It employs a form of polyalphabetic substitution. 
 *
 * ### Algorithm
 * The encryption can also be represented using modular arithmetic by first transforming 
 * the letters into numbers, according to the scheme, A → 0, B → 1, ..., Z → 25.
 * Encryption of \f$i^{th}\f$ character in Message M by key K can be described mathematically as,
 * 
 * \f[ E_{K}(M_{i}) = (M_{i} + K_{i})\;\mbox{mod}\; 26\f]
 * 
 * while decryption of \f$i^{th}\f$ character in Cipher C by key K can be described mathematically as,
 *
 * \f[ D_{k}(C_{i}) = (C_{i} - K_{i} + 26)\;\mbox{mod}\; 26\f]
 * 
 * Where \f$K_{i}\f$ denotes corresponding character in key. If \f$|key| < |text|\f$ than
 * same key is repeated untill their lengths are equal.
 * 
 * For Example,
 * If M = "ATTACKATDAWN" and K = "LEMON" than K becomes "LEMONLEMONLE".
 * 
 * \note Rather than creating new key of equal length this program does this by using modular index for key
 * (i.e. \f$(j + 1) \;\mbox{mod}\; |\mbox{key}|\f$)
 * 
 * \note This program implements Vigenère cipher for only uppercase English alphabet characters (i.e. A-Z). 
 * 
 * @author [Deep Raval](https://github.com/imdeep2905)
 */
#include <iostream>
#include <string>
#include <cassert>

/** \namespace ciphers
 * \brief Algorithms for encryption and decryption
 */
namespace ciphers {
    /** \namespace vigenere
     * \brief Functions for [vigenère cipher](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher) algorithm.
     */
    namespace vigenere {   
        namespace {
            /**
             * This function finds character for given value (i.e.A-Z)
             * @param x value for which we want character 
             * @return  corresponding character for perticular value
             */        
            inline char get_char(const int x) {
                // By adding 65 we are scaling 0-25 to 65-90. 
                // Which are in fact ASCII values of A-Z. 
                return char(x + 65); 
            }
            /**
             * This function finds value for given character (i.e.0-25)
             * @param c character for which we want value
             * @return returns corresponding value for perticular character
             */  
            inline int get_value(const char c) {
                // A-Z have ASCII values in range 65-90.
                // Hence subtracting 65 will scale them to 0-25.
                return int(c - 65);
            }
        } // Unnamed namespace
        /**
         * Encrypt given text using vigenere cipher.
         * @param text text to be encrypted
         * @param key to be used for encryption
         * @return new encrypted text
         */
        std::string encrypt (const std::string &text, const std::string &key) {
            std::string encrypted_text = ""; // Empty string to store encrypted text
            // Going through each character of text and key
            // Note that key is visited in circular way hence  j = (j + 1) % |key|
            for(size_t i = 0, j = 0; i < text.length(); i++, j = (j + 1) % key.length()) {
                int place_value_text = get_value(text[i]); // Getting value of character in text
                int place_value_key = get_value(key[j]); // Getting value of character in key
                place_value_text = (place_value_text + place_value_key) % 26; // Applying encryption
                char encrypted_char = get_char(place_value_text); // Getting new character from encrypted value
                encrypted_text += encrypted_char; // Appending encrypted character
            }
            return encrypted_text; // Returning encrypted text
        }
        /**
         * Decrypt given text using vigenere cipher.
         * @param text text to be decrypted
         * @param key key to be used for decryption
         * @return new decrypted text
         */        
        std::string decrypt (const std::string &text, const std::string &key) {
            // Going through each character of text and key
            // Note that key is visited in circular way hence  j = (j + 1) % |key|
            std::string decrypted_text = ""; // Empty string to store decrypted text
            for(size_t i = 0, j = 0; i < text.length(); i++, j = (j + 1) % key.length()) {
                int place_value_text = get_value(text[i]); // Getting value of character in text
                int place_value_key = get_value(key[j]); // Getting value of character in key
                place_value_text = (place_value_text - place_value_key + 26) % 26; // Applying decryption
                char decrypted_char = get_char(place_value_text); // Getting new character from decrypted value
                decrypted_text += decrypted_char; // Appending decrypted character
            }        
            return decrypted_text; // Returning decrypted text
        }
    } // namespace vigenere
} // namespace ciphers

/**
 * Function to test above algorithm
 */
void test() {
    // Test 1
    std::string text1 = "NIKOLATESLA";
    std::string encrypted1 = ciphers::vigenere::encrypt(text1, "TESLA");
    std::string decrypted1 = ciphers::vigenere::decrypt(encrypted1, "TESLA");
    assert(text1 == decrypted1);
    std::cout << "Original text : " << text1;
    std::cout << " , Encrypted text (with key = TESLA) : " << encrypted1;
    std::cout << " , Decrypted text : "<< decrypted1 << std::endl;
    // Test 2
    std::string text2 = "GOOGLEIT";
    std::string encrypted2 = ciphers::vigenere::encrypt(text2, "REALLY");
    std::string decrypted2 = ciphers::vigenere::decrypt(encrypted2, "REALLY");
    assert(text2 == decrypted2);
    std::cout << "Original text : " << text2;
    std::cout << " , Encrypted text (with key = REALLY) : " << encrypted2;
    std::cout << " , Decrypted text : "<< decrypted2 << std::endl;
}

/** Driver Code */
int main() {
    // Testing
    test();
    return 0;
}

示例二:

C++实现Vigenere密码加密和解密的示例:

#include <iostream>
#include <string>

std::string encryptVigenere(const std::string& plaintext, const std::string& keyword) {
    std::string ciphertext;
    int keywordLength = keyword.length();
    int plaintextLength = plaintext.length();

    for (int i = 0; i < plaintextLength; i++) {
        char currChar = plaintext[i];
        char keyChar = keyword[i % keywordLength];

        if (isalpha(currChar)) {
            char base = isupper(currChar) ? 'A' : 'a';
            char encryptedChar = (currChar - base + keyChar - 'A') % 26 + base;
            ciphertext += encryptedChar;
        } else {
            ciphertext += currChar;
        }
    }

    return ciphertext;
}

std::string decryptVigenere(const std::string& ciphertext, const std::string& keyword) {
    std::string plaintext;
    int keywordLength = keyword.length();
    int ciphertextLength = ciphertext.length();

    for (int i = 0; i < ciphertextLength; i++) {
        char currChar = ciphertext[i];
        char keyChar = keyword[i % keywordLength];

        if (isalpha(currChar)) {
            char base = isupper(currChar) ? 'A' : 'a';
            char decryptedChar = (currChar - keyChar + 26) % 26 + base;
            plaintext += decryptedChar;
        } else {
            plaintext += currChar;
        }
    }

    return plaintext;
}

int main() {
    std::string plaintext = "Hello World";
    std::string keyword = "KEY";

    std::string ciphertext = encryptVigenere(plaintext, keyword);
    std::cout << "Ciphertext: " << ciphertext << std::endl;

    std::string decryptedText = decryptVigenere(ciphertext, keyword);
    std::cout << "Decrypted text: " << decryptedText << std::endl;

    return 0;
}
        这个示例中的`encryptVigenere`函数实现了Vigenere密码的加密过程,而`decryptVigenere`函数实现了解密过程。在主函数中,我们使用了一个简单的明文("Hello World")和一个关键字("KEY")进行加密和解密。运行程序后,将输出加密后的密文和解密后的明文。请注意,这个示例假设明文和关键字只包含大写或小写字母。

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vigenere密码是一种多表密码,它使用多个不同的凯撒密码表。具体来说,对于明文中的每个字母,使用一个不同的凯撒密码表来将其加密。这样,相同的明文在不同位置上会被加密成不同的密文,增强了密码的安全性。 以下是使用C++实现Vigenere密码的示例代码: ```cpp #include <iostream> #include <string> using namespace std; string encrypt(string plaintext, string key) { string ciphertext = ""; int keyLen = key.length(); int i = 0; for (char& c : plaintext) { if (isalpha(c)) { int shift = key[i % keyLen] - 'a'; int base = isupper(c) ? 'A' : 'a'; c = (c - base + shift) % 26 + base; i++; } ciphertext += c; } return ciphertext; } string decrypt(string ciphertext, string key) { string plaintext = ""; int keyLen = key.length(); int i = 0; for (char& c : ciphertext) { if (isalpha(c)) { int shift = key[i % keyLen] - 'a'; int base = isupper(c) ? 'A' : 'a'; c = (c - base - shift + 26) % 26 + base; i++; } plaintext += c; } return plaintext; } int main() { string plaintext = "The quick brown fox jumps over the lazy dog"; string key = "lemon"; string ciphertext = encrypt(plaintext, key); string decrypted = decrypt(ciphertext, key); cout << "Plaintext: " << plaintext << endl; cout << "Key: " << key << endl; cout << "Ciphertext: " << ciphertext << endl; cout << "Decrypted: " << decrypted << endl; return 0; } ``` 在这个示例中,我们定义了两个函数:encrypt和decrypt。encrypt函数将明文和密钥作为输入,并返回加密后的密文。decrypt函数将密文和密钥作为输入,并返回解密后的明文。 在encrypt函数中,我们迭代明文中的每个字符。如果字符是字母,则我们计算出密钥中对应位置的偏移量,并使用凯撒密码的加密公式来加密该字符。注意,我们要将字符转换为大写或小写形式,以便在计算时使用ASCII编码中的正确偏移量。最后,我们将加密后的字符添加到密文中,然后返回整个密文字符串。 在decrypt函数中,我们执行与encrypt函数相反的操作。对于每个密文中的字符,我们计算出密钥中对应位置的偏移量,并使用凯撒密码的解密公式来解密该字符。最后,我们将解密后的字符添加到明文中,然后返回整个明文字符串。 在main函数中,我们定义了一个样例明文和密钥,并使用encrypt函数加密该明文。然后,我们使用decrypt函数解密该密文,并将结果打印到控制台上。 以上是一种简单的实现方法,Vigenere密码还有其他更高级的实现方式,例如使用矩阵代替凯撒密码表。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值