c++ Vigenere 密码

发布时间:2024年01月17日

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")进行加密和解密。运行程序后,将输出加密后的密文和解密后的明文。请注意,这个示例假设明文和关键字只包含大写或小写字母。

文章来源:https://blog.csdn.net/hefeng_aspnet/article/details/135641111
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。