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 (ตัวอย่าง)
| Plaintext | T | H | I | S | I | S | T | U | T | O | R | I | A | L | S | P | O | I | N | T |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Key (WELCOME...) | W | E | L | C | O | M | E | W | E | L | C | O | M | E | W | E | L | C | O | M |
| Ciphertext | P | L | T | U | W | E | X | Q | X | Z | T | W | M | P | O | T | Z | K | B | F |
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)