Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Cài đặt Vigenère Cipher trong C++

Vigenère Cipher là mật mã thay thế đa bảng (polyalphabetic) — cải tiến của Caesar Cipher bằng cách dùng khóa lặp lại để xác định độ dịch chuyển khác nhau cho từng vị trí.

Nguyên lý

  • Khóa K lặp lại để khớp độ dài bản rõ P.
  • Mã hóa: C[i] = (P[i] + K[i]) mod 26
  • Giải mã: P[i] = (C[i] - K[i] + 26) mod 26
  • Chỉ xử lý chữ cái A-Z/a-z, bỏ qua ký tự khác.

Bảng Vigenère (Tabula Recta)

Ma trận 26x26 các hàng Caesar Cipher dịch chuyển lần lượt 0..25. Hàng = bản rõ, cột = khóa, giao = bản mã.

Chương trình hoàn chỉnh (OOP)

#include <iostream>
#include <string>
#include <cctype>

using namespace std;

class Vigenere {
    string key; // Khóa đã chuẩn hóa (chỉ A-Z)
public:
    Vigenere(string k) {
        for (char ch : k) {
            if (isupper(ch)) key += ch;
            else if (islower(ch)) key += toupper(ch);
        }
    }
    
    string encrypt(const string& plaintext) {
        string cipher;
        for (size_t i = 0, j = 0; i < plaintext.size(); ++i) {
            char ch = plaintext[i];
            if (isalpha(ch)) {
                char base = isupper(ch) ? 'A' : 'a';
                int p = ch - base;
                int k = key[j % key.size()] - 'A';
                int c = (p + k) % 26;
                cipher += char(base + c);
                ++j; // Chỉ tăng chỉ số khóa khi xử lý chữ cái
            } else {
                cipher += ch; // Giữ nguyên ký tự khác
            }
        }
        return cipher;
    }
    
    string decrypt(const string& ciphertext) {
        string plain;
        for (size_t i = 0, j = 0; i < ciphertext.size(); ++i) {
            char ch = ciphertext[i];
            if (isalpha(ch)) {
                char base = isupper(ch) ? 'A' : 'a';
                int c = ch - base;
                int k = key[j % key.size()] - 'A';
                int p = (c - k + 26) % 26;
                plain += char(base + p);
                ++j;
            } else {
                plain += ch;
            }
        }
        return plain;
    }
};

int main() {
    Vigenere cipher("WELCOME");
    string original = "This is TutorialsPoint";
    
    string encrypted = cipher.encrypt(original);
    string decrypted = cipher.decrypt(encrypted);
    
    cout << "Ban ro:     " << original << '\n';
    cout << "Ban ma:     " << encrypted << '\n';
    cout << "Giai ma:    " << decrypted << '\n';
    return 0;
}

Kết quả

Ban ro:     This is TutorialsPoint
Ban ma:     Pltu Wex Qxztwm Potzkbf
Giai ma:    This is TutorialsPoint

Lưu ý: Kết quả có thể khác ví dụ gốc do xử lý khoảng trắng và case-insensitive key.

Phân tích bảo mật

  • Không gian khóa: 26^L với L độ dài khóa (rất lớn nếu khóa dài).
  • Kháng cự phân tích tần suất đơn biến — nhưng vẫn yếu trước Kasiski examination và Friedman test (xác định độ dài khóa).
  • An toàn nếu khóa: ngẫu nhiên, dài ≥ bản rõ, chỉ dùng một lần (One-Time Pad).

So sánh với Caesar & Affine

Mật mãLoạiKhóaĐộ an toàn
CaesarMonoalphabetic1 số (0-25)Rất yếu (26 khóa)
AffineMonoalphabetic2 số (a,b)Yếu (312 khóa)
VigenèrePolyalphabeticChuỗi ký tựTrung bình (phụ thuộc độ dài khóa)

Mẹo triển khai

  • Chuẩn hóa khóa: loại bỏ non-alpha, chuyển về uppercase.
  • Bảo toàn case của bản rõ (A→A, a→a).
  • Bỏ qua ký tự không phải chữ cái (space, punctuation, số) — không tăng chỉ số khóa.
  • Dùng (x + 26) % 26 khi trừ để tránh modulo âm trong C++.

Vigenère là bước tiến quan trọng trong lịch sử mật mã học, cầu nối giữa mật mã cổ điển và hiện đại.