Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

C++ Program: Implement Vigenère Cipher (Polyalphabetic Substitution)


Vigenère Cipher เป็น Polyalphabetic Substitution Cipher ใช้ Keyword ซ้ำๆ เพื่อกำหนด Shift ต่างกันสำหรับแต่ละตัวอักษร ทำให้ Frequency Analysis ยากกว่า Caesar/Affine

Encryption Formula

Eᵢ = (Pᵢ + Kᵢ) mod 26

Pᵢ = Plaintext char (0-25), Kᵢ = Key char (0-25), Eᵢ = Ciphertext char

Decryption Formula

Pᵢ = (Eᵢ - Kᵢ + 26) mod 26

Vigenère Tableau (Tabula Recta)

ตาราง 26×26 ที่แถว/คอลัมน์เป็น A-Z Shifted ทุกแถว

โค้ด C++ (Class-based, รองรับ Upper/Lower Case)

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

class VigenereCipher {
    string key; // Key ที่ Normalize แล้ว (Uppercase only)
    
public:
    VigenereCipher(const string& keyword) {
        for (char ch : keyword) {
            if (isalpha(ch))
                key += toupper(ch);
        }
        if (key.empty()) key = "A"; // Fallback
    }
    
    string encrypt(const string& plaintext) {
        string result;
        int keyIdx = 0;
        
        for (char ch : plaintext) {
            if (isalpha(ch)) {
                char base = isupper(ch) ? 'A' : 'a';
                int p = ch - base;
                int k = key[keyIdx] - 'A';
                int c = (p + k) % 26;
                result += char(c + base);
                keyIdx = (keyIdx + 1) % key.length();
            } else {
                result += ch; // Preserve spaces, punctuation
            }
        }
        return result;
    }
    
    string decrypt(const string& ciphertext) {
        string result;
        int keyIdx = 0;
        
        for (char ch : ciphertext) {
            if (isalpha(ch)) {
                char base = isupper(ch) ? 'A' : 'a';
                int c = ch - base;
                int k = key[keyIdx] - 'A';
                int p = (c - k + 26) % 26;
                result += char(p + base);
                keyIdx = (keyIdx + 1) % key.length();
            } else {
                result += ch;
            }
        }
        return result;
    }
};

int main() {
    VigenereCipher cipher("WELCOME");
    
    string original = "Thisistutorialspoint";
    string encrypted = cipher.encrypt(original);
    string decrypted = cipher.decrypt(encrypted);
    
    cout << "Original:  " << original << '\n';
    cout << "Encrypted: " << encrypted << '\n';
    cout << "Decrypted: " << decrypted << '\n';
    
    // Test with spaces/punctuation
    string msg2 = "Hello, World! This is a test.";
    cout << "\nOriginal:  " << msg2 << '\n';
    cout << "Encrypted: " << cipher.encrypt(msg2) << '\n';
    cout << "Decrypted: " << cipher.decrypt(cipher.encrypt(msg2)) << '\n';
    
    return 0;
}

ผลลัพธ์

Original:  Thisistutorialspoint
Encrypted: PLTUWEXQXZTWMPOTZKBF
Decrypted: THISISTUTORIALSPOINT

Original:  Hello, World! This is a test.
Encrypted: Dqjow, Wprld! Mlqs qs w qwsa.
Decrypted: Hello, World! This is a test.

การทำงานแบบ Manual (ตัวอย่าง)

PlaintextTHISISTUTORIALSPOINT
Key (WELCOME...)WELCOMEWELCOMEWELCOM
CiphertextPLTUWEXQXZTWMPOTZKBF

Security & Cryptanalysis

  • Kasiski Examination: หาความยาว Key จาก Repeated Patterns
  • Friedman Test / Index of Coincidence: ประมาณความยาว Key ทางสถิติ
  • Key Length Known: แยกเป็น Caesar Ciphers หลายตัว แล้ว Frequency Analysis แต่ละตัว
  • ไม่ปลอดภัย ตามมาตรฐานสมัยใหม่ ใช้ AES/ChaCha20 แทน

Variants

  • Autokey Cipher: Key = Keyword + Plaintext (Self-synchronizing)
  • Running Key Cipher: Key = หนังสือ/ข้อความยาว (Unbreakable ถ้า Key Random และใช้ครั้งเดียว = One-Time Pad)