Chiffre César

Python Caesar Cipher: tutoriel de programmation complet avec le code source

Tutoriel complet sur le chiffrement Python César avec des exemples de code source, des applications GUI, des outils de cryptanalyse et des implémentations professionnelles. Parfait pour les apprenants Python et les programmeurs de cryptographie.

Publié sur 11 août 2025
12 min lire
Guides CaesarCipher.org
Couverture de la programmation du chiffrement Python Caesar montrant des extraits de code, l'interface IDE, l'implémentation de l'algorithme et des exemples complets de code source avec coloration syntaxique
Programmation du chiffrement Python César: didacticiel complet avec exemples de code source

Python est devenu le langage incontournable pour l'enseignement de la cryptographie et le développement d'outils de sécurité pratiques, offrant une combinaison parfaite de simplicité, de lisibilité et de bibliothèques puissantes qui rendent les algorithmes complexes accessibles aux débutants tout en prenant en charge des implémentations de niveau professionnel. Le chiffre César représente un point de départ idéal pour les programmeurs Python intéressés par la cryptographie, fournissant des bases mathématiques claires et des applications pratiques immédiates qui démontrent les concepts de programmation de base.

Ce que vous allez construire dans ce didacticiel Python

🔧 Fonctions de base du chiffre César - Algorithmes de cryptage/déchiffrement de base avec gestion des erreurs
📊 Outils de cryptanalyse - Fonctions d'analyse de fréquence et de décryptage automatisé
🖥️ Application GUI - Interface interactive Tkinter pour le cryptage/déchiffrement en temps réel
📁 Traitement des fichiers - Crypter/déchiffrer par lots des fichiers texte entiers avec des indicateurs de progression
Optimisation des performances - Implémentations efficaces pour le traitement de texte à grande échelle
🧪 Testing Suite - Effectuez des tests unitaires pour valider vos implémentations

Ce didacticiel complet vous guide dans la mise en œuvre des algorithmes de chiffrement Caesar, depuis les fonctions de base jusqu'aux applications sophistiquées, y compris les interfaces GUI, les outils de cryptanalyse automatisés et les implémentations de niveau professionnel adaptées au déploiement dans le monde réel. Que vous soyez un débutant Python apprenant les concepts fondamentaux de la programmation ou un développeur expérimenté explorant les applications cryptographiques, vous découvrirez des techniques pratiques et des exemples complets de code source qui accélèrent votre processus d'apprentissage et de développement.

Le didacticiel passe systématiquement des fonctions de chiffrement simples aux fonctionnalités avancées, notamment l'analyse de fréquence, le décryptage automatisé, les applications GUI interactives et les techniques d'optimisation des performances. Chaque exemple de code comprend des explications détaillées, des recommandations de bonnes pratiques et des scénarios d'application réels qui relient les concepts théoriques aux compétences pratiques en programmation.

Les atouts de Python en matière de manipulation de chaînes, d'opérations mathématiques et de développement d'interfaces utilisateur le rendent particulièrement adapté à l'enseignement cryptographique et à la création d'outils. La vaste bibliothèque standard du langage et son écosystème tiers fournissent tout le nécessaire pour les applications de cryptanalyse sophistiquées tout en conservant la clarté et la maintenabilité du code qui soutiennent l'apprentissage et la collaboration.

Pour les apprenants Python, ce projet démontre les concepts de programmation essentiels, notamment les fonctions, les classes, la gestion des erreurs, les opérations sur les fichiers et le développement d'interfaces graphiques, à travers une application attrayante et pratique. Les passionnés de cryptographie apprécieront les fondements mathématiques, l'analyse algorithmique et les fonctionnalités avancées qui étendent les implémentations de base en outils de qualité professionnelle adaptés aux applications éducatives et de recherche.

Bases du chiffrement Python César

Comprendre l'algorithme

Le chiffre de César implémente une transformation mathématique simple qui décale chaque lettre de l'alphabet d'un nombre fixe de positions. En Python, nous pouvons exprimer cela mathématiquement comme (x + n) % 26 pour le chiffrement, où x représente la position de la lettre (A=0, B=1, etc.) et n est la valeur de décalage. L'opération modulo garantit que les décalages s'enroulent autour de l'alphabet: lorsque le calcul dépasse Z, il revient au début.

Fondements mathématiques en Python:

# Encryption: (position + shift) % alphabet_size
# Decryption: (position - shift) % alphabet_size

def get_letter_position(letter):
    """Convert letter to numeric position (A=0, B=1, etc.)"""
    return ord(letter.upper()) - ord('A')

def position_to_letter(position):
    """Convert numeric position back to letter"""
    return chr(position + ord('A'))

Considérations sur la gestion des personnages: Les méthodes de chaîne intégrées de Python et les fonctions ASCII fournissent des solutions élégantes pour la manipulation de caractères. La fonction ord() convertit les caractères en valeurs ASCII, tandis que chr() les reconvertit en caractères. Cette approche gère à la fois les lettres majuscules et minuscules tout en préservant les relations mathématiques requises pour les opérations de chiffrement César.

# ASCII value manipulation examples
print(ord('A'))  # Output: 65
print(ord('Z'))  # Output: 90
print(chr(65))   # Output: 'A'
print(chr(90))   # Output: 'Z'

# Calculate shift position
letter = 'H'
shift = 3
position = ord(letter) - ord('A')  # H = position 7
new_position = (position + shift) % 26  # (7 + 3) % 26 = 10
result = chr(new_position + ord('A'))  # Position 10 = 'K'

Concepts Python essentiels

Manipulation et itération de chaînes: La mise en œuvre du chiffrement César repose en grande partie sur le traitement des chaînes et la transformation caractère par caractère. Les capacités d'itération de chaînes et de compréhension de listes de Python fournissent des approches efficaces et lisibles du traitement de texte:

def process_text_basic(text, shift):
    """Demonstrate basic string processing for Caesar cipher"""
    result = ""

    # Method 1: Traditional for loop
    for char in text:
        if char.isalpha():
            # Process alphabetic characters
            base = ord('A') if char.isupper() else ord('a')
            shifted = (ord(char) - base + shift) % 26
            result += chr(shifted + base)
        else:
            # Preserve non-alphabetic characters
            result += char

    return result

# Method 2: List comprehension (more Pythonic)
def process_text_comprehension(text, shift):
    """List comprehension approach for cleaner code"""
    return ''.join([
        chr((ord(char) - ord('A') + shift) % 26 + ord('A'))
        if char.isupper() else
        chr((ord(char) - ord('a') + shift) % 26 + ord('a'))
        if char.islower() else char
        for char in text
    ])

Arithmétique modulaire et cas extrêmes: L'opérateur modulo (%) gère automatiquement le bouclage de l'alphabet, mais la compréhension des cas extrêmes garantit des implémentations robustes:

def demonstrate_modulo_arithmetic():
    """Show how modulo handles alphabet wraparound"""
    examples = [
        ('Z', 1),   # Z + 1 should become A
        ('A', -1),  # A - 1 should become Z
        ('M', 13),  # Middle letter with ROT13
        ('Z', 25)   # Maximum shift
    ]

    for letter, shift in examples:
        pos = ord(letter) - ord('A')
        new_pos = (pos + shift) % 26
        result = chr(new_pos + ord('A'))
        print(f"{letter} + {shift} = {result}")

    # Handle negative shifts properly
    def safe_modulo(value, modulus):
        """Ensure positive result for negative inputs"""
        return ((value % modulus) + modulus) % modulus

Guide complet de mise en œuvre de Python

Fonction de chiffrement César simple

Voici une implémentation complète et conviviale pour les débutants avec des commentaires détaillés et une gestion des erreurs:

def caesar_encrypt(text, shift):
    """
    Encrypt text using Caesar cipher with specified shift.

    Args:
        text (str): The plaintext to encrypt
        shift (int): Number of positions to shift (positive for right, negative for left)

    Returns:
        str: The encrypted ciphertext

    Example:
        >>> caesar_encrypt("HELLO WORLD", 3)
        'KHOOR ZRUOG'
    """
    # Input validation
    if not isinstance(text, str):
        raise TypeError("Text must be a string")
    if not isinstance(shift, int):
        raise TypeError("Shift must be an integer")

    # Normalize shift to valid range (0-25)
    shift = shift % 26

    result = []

    for char in text:
        if char.isalpha():
            # Determine if uppercase or lowercase
            is_upper = char.isupper()

            # Convert to uppercase for calculation
            char_upper = char.upper()

            # Calculate shifted position
            char_position = ord(char_upper) - ord('A')
            shifted_position = (char_position + shift) % 26

            # Convert back to character
            new_char = chr(shifted_position + ord('A'))

            # Maintain original case
            result.append(new_char if is_upper else new_char.lower())
        else:
            # Preserve non-alphabetic characters (spaces, punctuation, numbers)
            result.append(char)

    return ''.join(result)


def caesar_decrypt(ciphertext, shift):
    """
    Decrypt Caesar cipher by shifting in opposite direction.

    Args:
        ciphertext (str): The encrypted text to decrypt
        shift (int): The shift value used for encryption

    Returns:
        str: The decrypted plaintext
    """
    return caesar_encrypt(ciphertext, -shift)


# Test the implementation
if __name__ == "__main__":
    # Basic test examples
    plaintext = "Hello, World! This is a test message."
    shift_value = 3

    print(f"Original: {plaintext}")

    encrypted = caesar_encrypt(plaintext, shift_value)
    print(f"Encrypted: {encrypted}")

    decrypted = caesar_decrypt(encrypted, shift_value)
    print(f"Decrypted: {decrypted}")

    # Verify round-trip encryption/decryption
    assert plaintext == decrypted, "Encryption/decryption failed!"
    print("✓ Encryption/decryption successful!")

Version améliorée avec plusieurs fonctionnalités

Cette implémentation avancée inclut des options de configuration, des alphabets personnalisés et une gestion professionnelle des erreurs:

import string
import re
from typing import Optional, Union

class AdvancedCaesarCipher:
    """
    Advanced Caesar cipher implementation with multiple features and configurations.
    """

    def __init__(self,
                 preserve_case: bool = True,
                 preserve_non_alpha: bool = True,
                 custom_alphabet: Optional[str] = None):
        """
        Initialize cipher with configuration options.

        Args:
            preserve_case: Whether to maintain original letter case
            preserve_non_alpha: Whether to keep non-alphabetic characters unchanged
            custom_alphabet: Custom alphabet string (default: English A-Z)
        """
        self.preserve_case = preserve_case
        self.preserve_non_alpha = preserve_non_alpha
        self.alphabet = custom_alphabet or string.ascii_uppercase
        self.alphabet_size = len(self.alphabet)

        # Create lookup dictionaries for performance
        self.char_to_index = {char: i for i, char in enumerate(self.alphabet)}
        self.index_to_char = {i: char for i, char in enumerate(self.alphabet)}

    def encrypt(self, text: str, shift: int) -> str:
        """
        Encrypt text with Caesar cipher.

        Args:
            text: Text to encrypt
            shift: Shift value (positive for right shift)

        Returns:
            Encrypted text
        """
        return self._transform_text(text, shift)

    def decrypt(self, ciphertext: str, shift: int) -> str:
        """
        Decrypt Caesar cipher text.

        Args:
            ciphertext: Encrypted text to decrypt
            shift: Shift value used for encryption

        Returns:
            Decrypted text
        """
        return self._transform_text(ciphertext, -shift)

    def _transform_text(self, text: str, shift: int) -> str:
        """
        Internal method to transform text with given shift.
        """
        if not text:
            return ""

        shift = shift % self.alphabet_size
        result = []

        for char in text:
            if char.upper() in self.char_to_index:
                # Process alphabetic characters
                char_upper = char.upper()
                old_index = self.char_to_index[char_upper]
                new_index = (old_index + shift) % self.alphabet_size
                new_char = self.index_to_char[new_index]

                # Apply case preservation
                if self.preserve_case and char.islower():
                    new_char = new_char.lower()

                result.append(new_char)
            else:
                # Handle non-alphabetic characters
                if self.preserve_non_alpha:
                    result.append(char)
                # Otherwise skip the character

        return ''.join(result)

    def bulk_encrypt(self, texts: list, shift: int) -> list:
        """
        Encrypt multiple texts with the same shift.

        Args:
            texts: List of texts to encrypt
            shift: Shift value

        Returns:
            List of encrypted texts
        """
        return [self.encrypt(text, shift) for text in texts]

    def try_all_shifts(self, ciphertext: str) -> dict:
        """
        Try decryption with all possible shift values.

        Args:
            ciphertext: Text to decrypt

        Returns:
            Dictionary mapping shift values to decrypted results
        """
        results = {}
        for shift in range(self.alphabet_size):
            decrypted = self.decrypt(ciphertext, shift)
            results[shift] = decrypted
        return results

    def analyze_frequency(self, text: str) -> dict:
        """
        Analyze letter frequency in given text.

        Args:
            text: Text to analyze

        Returns:
            Dictionary mapping letters to their frequencies
        """
        # Convert to uppercase and filter only alphabet characters
        clean_text = ''.join(char.upper() for char in text if char.upper() in self.alphabet)
        total_chars = len(clean_text)

        if total_chars == 0:
            return {}

        frequency = {}
        for char in self.alphabet:
            count = clean_text.count(char)
            frequency[char] = count / total_chars

        return frequency


# Usage examples and testing
def demonstrate_advanced_features():
    """Demonstrate advanced cipher features"""

    # Initialize cipher with default settings
    cipher = AdvancedCaesarCipher()

    # Test data
    test_message = "The Quick Brown Fox Jumps Over The Lazy Dog! 123"
    shift = 13  # ROT13

    print("=== Advanced Caesar Cipher Demo ===")
    print(f"Original: {test_message}")

    # Basic encryption/decryption
    encrypted = cipher.encrypt(test_message, shift)
    print(f"Encrypted (ROT13): {encrypted}")

    decrypted = cipher.decrypt(encrypted, shift)
    print(f"Decrypted: {decrypted}")

    # Try all possible shifts
    print("\n=== All Possible Shifts ===")
    all_shifts = cipher.try_all_shifts("KHOOR")
    for shift_val, result in all_shifts.items():
        print(f"Shift {shift_val:2d}: {result}")

    # Frequency analysis
    print("\n=== Frequency Analysis ===")
    sample_text = "This is a sample text for frequency analysis testing"
    frequencies = cipher.analyze_frequency(sample_text)

    # Sort by frequency (descending)
    sorted_freq = sorted(frequencies.items(), key=lambda x: x[1], reverse=True)
    print("Letter frequencies:")
    for letter, freq in sorted_freq[:10]:  # Top 10
        if freq > 0:
            print(f"  {letter}: {freq:.3f} ({freq*100:.1f}%)")

    # Custom alphabet example
    print("\n=== Custom Alphabet Example ===")
    custom_cipher = AdvancedCaesarCipher(custom_alphabet="0123456789")
    numbers = "1234567890"
    encrypted_nums = custom_cipher.encrypt(numbers, 3)
    print(f"Numbers: {numbers}")
    print(f"Shifted:  {encrypted_nums}")


if __name__ == "__main__":
    demonstrate_advanced_features()

Implémentation orientée objet

Voici une implémentation complète basée sur des classes de qualité professionnelle, adaptée à une utilisation en production:

import json
import os
from pathlib import Path
from typing import Dict, List, Optional, Tuple
import logging

class ProfessionalCaesarCipher:
    """
    Professional-grade Caesar cipher implementation with comprehensive features.

    Features:
    - Multiple encryption/decryption modes
    - File processing capabilities
    - Configuration management
    - Logging and error handling
    - Statistical analysis tools
    - Export/import functionality
    """

    # English letter frequencies for cryptanalysis
    ENGLISH_FREQ = {
        'A': 0.08167, 'B': 0.01492, 'C': 0.02782, 'D': 0.04253,
        'E': 0.12702, 'F': 0.02228, 'G': 0.02015, 'H': 0.06094,
        'I': 0.06966, 'J': 0.00153, 'K': 0.00772, 'L': 0.04025,
        'M': 0.02406, 'N': 0.06749, 'O': 0.07507, 'P': 0.01929,
        'Q': 0.00095, 'R': 0.05987, 'S': 0.06327, 'T': 0.09056,
        'U': 0.02758, 'V': 0.00978, 'W': 0.02360, 'X': 0.00150,
        'Y': 0.01974, 'Z': 0.00074
    }

    def __init__(self, config_file: Optional[str] = None):
        """
        Initialize the cipher with optional configuration.

        Args:
            config_file: Path to JSON configuration file
        """
        # Set up logging
        logging.basicConfig(level=logging.INFO)
        self.logger = logging.getLogger(__name__)

        # Default configuration
        self.config = {
            'preserve_case': True,
            'preserve_spaces': True,
            'preserve_punctuation': True,
            'default_shift': 3,
            'alphabet': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
        }

        # Load configuration if provided
        if config_file and os.path.exists(config_file):
            self.load_config(config_file)

        self.alphabet_size = len(self.config['alphabet'])

    def load_config(self, config_file: str) -> None:
        """Load configuration from JSON file."""
        try:
            with open(config_file, 'r') as f:
                user_config = json.load(f)
                self.config.update(user_config)
            self.logger.info(f"Configuration loaded from {config_file}")
        except Exception as e:
            self.logger.error(f"Failed to load config: {e}")
            raise

    def save_config(self, config_file: str) -> None:
        """Save current configuration to JSON file."""
        try:
            with open(config_file, 'w') as f:
                json.dump(self.config, f, indent=2)
            self.logger.info(f"Configuration saved to {config_file}")
        except Exception as e:
            self.logger.error(f"Failed to save config: {e}")
            raise

    def encrypt(self, text: str, shift: Optional[int] = None) -> str:
        """
        Encrypt text using Caesar cipher.

        Args:
            text: Text to encrypt
            shift: Shift value (uses default if None)

        Returns:
            Encrypted text
        """
        if shift is None:
            shift = self.config['default_shift']

        self.logger.debug(f"Encrypting text with shift {shift}")
        return self._transform(text, shift)

    def decrypt(self, ciphertext: str, shift: Optional[int] = None) -> str:
        """
        Decrypt Caesar cipher text.

        Args:
            ciphertext: Text to decrypt
            shift: Shift value used for encryption

        Returns:
            Decrypted text
        """
        if shift is None:
            shift = self.config['default_shift']

        self.logger.debug(f"Decrypting text with shift {shift}")
        return self._transform(ciphertext, -shift)

    def _transform(self, text: str, shift: int) -> str:
        """Internal transformation method."""
        if not text:
            return ""

        shift = shift % self.alphabet_size
        result = []

        for char in text:
            if char.upper() in self.config['alphabet']:
                # Transform alphabetic characters
                is_lower = char.islower()
                char_upper = char.upper()

                old_pos = self.config['alphabet'].index(char_upper)
                new_pos = (old_pos + shift) % self.alphabet_size
                new_char = self.config['alphabet'][new_pos]

                if self.config['preserve_case'] and is_lower:
                    new_char = new_char.lower()

                result.append(new_char)
            elif char.isspace() and self.config['preserve_spaces']:
                result.append(char)
            elif not char.isalnum() and self.config['preserve_punctuation']:
                result.append(char)
            # Skip character if none of the preservation options apply

        return ''.join(result)

    def process_file(self, input_file: str, output_file: str,
                    shift: int, encrypt: bool = True) -> None:
        """
        Process entire file with Caesar cipher.

        Args:
            input_file: Path to input file
            output_file: Path to output file
            shift: Shift value
            encrypt: True for encryption, False for decryption
        """
        try:
            with open(input_file, 'r', encoding='utf-8') as infile:
                content = infile.read()

            if encrypt:
                processed_content = self.encrypt(content, shift)
                operation = "encrypted"
            else:
                processed_content = self.decrypt(content, shift)
                operation = "decrypted"

            with open(output_file, 'w', encoding='utf-8') as outfile:
                outfile.write(processed_content)

            self.logger.info(f"File {operation} successfully: {input_file} -> {output_file}")

        except Exception as e:
            self.logger.error(f"File processing failed: {e}")
            raise

    def frequency_analysis(self, text: str) -> Dict[str, float]:
        """
        Perform frequency analysis on text.

        Args:
            text: Text to analyze

        Returns:
            Dictionary of letter frequencies
        """
        # Clean text (uppercase letters only)
        clean_text = ''.join(c.upper() for c in text if c.upper() in self.config['alphabet'])

        if not clean_text:
            return {}

        total_chars = len(clean_text)
        frequencies = {}

        for char in self.config['alphabet']:
            count = clean_text.count(char)
            frequencies[char] = count / total_chars

        return frequencies

    def chi_squared_analysis(self, text: str) -> List[Tuple[int, float]]:
        """
        Perform chi-squared analysis to find most likely shift value.

        Args:
            text: Ciphertext to analyze

        Returns:
            List of (shift, chi_squared_score) tuples, sorted by score
        """
        results = []

        for shift in range(self.alphabet_size):
            # Try decryption with this shift
            decrypted = self.decrypt(text, shift)
            frequencies = self.frequency_analysis(decrypted)

            # Calculate chi-squared statistic
            chi_squared = 0.0
            for char in self.config['alphabet']:
                observed = frequencies.get(char, 0.0)
                expected = self.ENGLISH_FREQ[char]
                if expected > 0:
                    chi_squared += ((observed - expected) ** 2) / expected

            results.append((shift, chi_squared))

        # Sort by chi-squared value (lower is better)
        results.sort(key=lambda x: x[1])
        return results

    def auto_decrypt(self, ciphertext: str, num_candidates: int = 3) -> List[Tuple[int, str, float]]:
        """
        Automatically attempt to decrypt Caesar cipher using statistical analysis.

        Args:
            ciphertext: Text to decrypt
            num_candidates: Number of best candidates to return

        Returns:
            List of (shift, decrypted_text, score) tuples
        """
        chi_squared_results = self.chi_squared_analysis(ciphertext)
        candidates = []

        for shift, score in chi_squared_results[:num_candidates]:
            decrypted = self.decrypt(ciphertext, shift)
            candidates.append((shift, decrypted, score))

        return candidates

    def export_results(self, results: dict, filename: str) -> None:
        """
        Export analysis results to JSON file.

        Args:
            results: Results dictionary to export
            filename: Output filename
        """
        try:
            with open(filename, 'w') as f:
                json.dump(results, f, indent=2)
            self.logger.info(f"Results exported to {filename}")
        except Exception as e:
            self.logger.error(f"Export failed: {e}")
            raise


# Demonstration and testing
def main():
    """Demonstrate professional Caesar cipher implementation."""

    # Initialize cipher
    cipher = ProfessionalCaesarCipher()

    # Test message
    message = """
    The Caesar cipher is one of the earliest known and simplest ciphers.
    It is a type of substitution cipher in which each letter in the plaintext
    is 'shifted' a certain number of places down the alphabet.
    """

    print("=== Professional Caesar Cipher Demo ===")
    print(f"Original message:\n{message}")

    # Encrypt with default shift
    encrypted = cipher.encrypt(message)
    print(f"\nEncrypted:\n{encrypted}")

    # Decrypt
    decrypted = cipher.decrypt(encrypted)
    print(f"\nDecrypted:\n{decrypted}")

    # Demonstrate auto-decryption (simulate unknown shift)
    test_cipher = "WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ"
    print(f"\n=== Auto-Decryption Demo ===")
    print(f"Unknown ciphertext: {test_cipher}")

    candidates = cipher.auto_decrypt(test_cipher, num_candidates=5)
    print("\nTop candidates:")
    for i, (shift, text, score) in enumerate(candidates, 1):
        print(f"{i}. Shift {shift:2d} (χ² = {score:.3f}): {text}")

    # Frequency analysis
    print(f"\n=== Frequency Analysis ===")
    frequencies = cipher.frequency_analysis(message)
    sorted_freq = sorted(frequencies.items(), key=lambda x: x[1], reverse=True)

    print("Top letter frequencies:")
    for letter, freq in sorted_freq[:10]:
        if freq > 0:
            print(f"  {letter}: {freq:.3f} ({freq*100:.1f}%)")


if __name__ == "__main__":
    main()

Développement d'applications GUI

Interface basée sur Tkinter

Voici une application GUI complète utilisant la bibliothèque Tkinter intégrée de Python:

import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox, filedialog
import threading
from typing import Optional

class CaesarCipherGUI:
    """
    Complete GUI application for Caesar cipher operations.

    Features:
    - Real-time encryption/decryption
    - File processing
    - Automated cryptanalysis
    - Results export
    - User-friendly interface
    """

    def __init__(self):
        self.root = tk.Tk()
        self.root.title("Caesar Cipher Tool - Professional Edition")
        self.root.geometry("800x600")

        # Initialize cipher backend
        self.cipher = ProfessionalCaesarCipher()

        # Create GUI elements
        self.setup_gui()

        # Bind events
        self.setup_events()

    def setup_gui(self):
        """Create and arrange GUI elements."""

        # Main notebook for tabs
        self.notebook = ttk.Notebook(self.root)
        self.notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # Create tabs
        self.create_encrypt_tab()
        self.create_decrypt_tab()
        self.create_analysis_tab()
        self.create_file_tab()

        # Status bar
        self.status_var = tk.StringVar()
        self.status_var.set("Ready")
        status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN)
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)

    def create_encrypt_tab(self):
        """Create encryption tab."""
        encrypt_frame = ttk.Frame(self.notebook)
        self.notebook.add(encrypt_frame, text="Encrypt")

        # Input section
        input_frame = ttk.LabelFrame(encrypt_frame, text="Input Text")
        input_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        self.encrypt_input = scrolledtext.ScrolledText(input_frame, height=10)
        self.encrypt_input.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # Controls
        control_frame = ttk.Frame(encrypt_frame)
        control_frame.pack(fill=tk.X, padx=10, pady=5)

        ttk.Label(control_frame, text="Shift:").pack(side=tk.LEFT)
        self.encrypt_shift = tk.IntVar(value=3)
        shift_spin = ttk.Spinbox(control_frame, from_=1, to=25, textvariable=self.encrypt_shift, width=10)
        shift_spin.pack(side=tk.LEFT, padx=(5, 10))

        ttk.Button(control_frame, text="Encrypt", command=self.encrypt_text).pack(side=tk.LEFT, padx=5)
        ttk.Button(control_frame, text="Clear", command=self.clear_encrypt).pack(side=tk.LEFT, padx=5)
        ttk.Button(control_frame, text="Copy Result", command=self.copy_encrypt_result).pack(side=tk.LEFT, padx=5)

        # Output section
        output_frame = ttk.LabelFrame(encrypt_frame, text="Encrypted Text")
        output_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        self.encrypt_output = scrolledtext.ScrolledText(output_frame, height=10, state=tk.DISABLED)
        self.encrypt_output.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

    def create_decrypt_tab(self):
        """Create decryption tab."""
        decrypt_frame = ttk.Frame(self.notebook)
        self.notebook.add(decrypt_frame, text="Decrypt")

        # Input section
        input_frame = ttk.LabelFrame(decrypt_frame, text="Encrypted Text")
        input_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        self.decrypt_input = scrolledtext.ScrolledText(input_frame, height=8)
        self.decrypt_input.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # Controls
        control_frame = ttk.Frame(decrypt_frame)
        control_frame.pack(fill=tk.X, padx=10, pady=5)

        ttk.Label(control_frame, text="Shift:").pack(side=tk.LEFT)
        self.decrypt_shift = tk.IntVar(value=3)
        shift_spin = ttk.Spinbox(control_frame, from_=1, to=25, textvariable=self.decrypt_shift, width=10)
        shift_spin.pack(side=tk.LEFT, padx=(5, 10))

        ttk.Button(control_frame, text="Decrypt", command=self.decrypt_text).pack(side=tk.LEFT, padx=5)
        ttk.Button(control_frame, text="Auto Decrypt", command=self.auto_decrypt).pack(side=tk.LEFT, padx=5)
        ttk.Button(control_frame, text="Clear", command=self.clear_decrypt).pack(side=tk.LEFT, padx=5)

        # Output section
        output_frame = ttk.LabelFrame(decrypt_frame, text="Decrypted Text")
        output_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        self.decrypt_output = scrolledtext.ScrolledText(output_frame, height=8, state=tk.DISABLED)
        self.decrypt_output.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

    def create_analysis_tab(self):
        """Create cryptanalysis tab."""
        analysis_frame = ttk.Frame(self.notebook)
        self.notebook.add(analysis_frame, text="Analysis")

        # Input section
        input_frame = ttk.LabelFrame(analysis_frame, text="Text to Analyze")
        input_frame.pack(fill=tk.X, padx=10, pady=5)

        self.analysis_input = scrolledtext.ScrolledText(input_frame, height=6)
        self.analysis_input.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # Controls
        control_frame = ttk.Frame(analysis_frame)
        control_frame.pack(fill=tk.X, padx=10, pady=5)

        ttk.Button(control_frame, text="Analyze All Shifts", command=self.analyze_all_shifts).pack(side=tk.LEFT, padx=5)
        ttk.Button(control_frame, text="Frequency Analysis", command=self.frequency_analysis).pack(side=tk.LEFT, padx=5)
        ttk.Button(control_frame, text="Export Results", command=self.export_analysis).pack(side=tk.LEFT, padx=5)

        # Results section
        results_frame = ttk.LabelFrame(analysis_frame, text="Analysis Results")
        results_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        # Treeview for results
        columns = ('Shift', 'Score', 'Preview')
        self.analysis_tree = ttk.Treeview(results_frame, columns=columns, show='headings', height=8)

        for col in columns:
            self.analysis_tree.heading(col, text=col)
            self.analysis_tree.column(col, width=100)

        # Scrollbar for treeview
        scrollbar = ttk.Scrollbar(results_frame, orient=tk.VERTICAL, command=self.analysis_tree.yview)
        self.analysis_tree.configure(yscrollcommand=scrollbar.set)

        self.analysis_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y, pady=5)

        # Detailed result display
        detail_frame = ttk.LabelFrame(analysis_frame, text="Detailed Result")
        detail_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        self.analysis_detail = scrolledtext.ScrolledText(detail_frame, height=6, state=tk.DISABLED)
        self.analysis_detail.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # Bind treeview selection
        self.analysis_tree.bind('<<TreeviewSelect>>', self.on_analysis_select)

    def create_file_tab(self):
        """Create file processing tab."""
        file_frame = ttk.Frame(self.notebook)
        self.notebook.add(file_frame, text="File Processing")

        # File selection
        file_select_frame = ttk.LabelFrame(file_frame, text="File Selection")
        file_select_frame.pack(fill=tk.X, padx=10, pady=5)

        # Input file
        ttk.Label(file_select_frame, text="Input File:").grid(row=0, column=0, sticky=tk.W, padx=5, pady=2)
        self.input_file_var = tk.StringVar()
        ttk.Entry(file_select_frame, textvariable=self.input_file_var, width=50).grid(row=0, column=1, padx=5, pady=2)
        ttk.Button(file_select_frame, text="Browse", command=self.browse_input_file).grid(row=0, column=2, padx=5, pady=2)

        # Output file
        ttk.Label(file_select_frame, text="Output File:").grid(row=1, column=0, sticky=tk.W, padx=5, pady=2)
        self.output_file_var = tk.StringVar()
        ttk.Entry(file_select_frame, textvariable=self.output_file_var, width=50).grid(row=1, column=1, padx=5, pady=2)
        ttk.Button(file_select_frame, text="Browse", command=self.browse_output_file).grid(row=1, column=2, padx=5, pady=2)

        # Processing options
        options_frame = ttk.LabelFrame(file_frame, text="Processing Options")
        options_frame.pack(fill=tk.X, padx=10, pady=5)

        ttk.Label(options_frame, text="Shift:").grid(row=0, column=0, sticky=tk.W, padx=5, pady=2)
        self.file_shift = tk.IntVar(value=3)
        ttk.Spinbox(options_frame, from_=1, to=25, textvariable=self.file_shift, width=10).grid(row=0, column=1, padx=5, pady=2, sticky=tk.W)

        self.file_operation = tk.StringVar(value="encrypt")
        ttk.Radiobutton(options_frame, text="Encrypt", variable=self.file_operation, value="encrypt").grid(row=0, column=2, padx=20, pady=2)
        ttk.Radiobutton(options_frame, text="Decrypt", variable=self.file_operation, value="decrypt").grid(row=0, column=3, padx=5, pady=2)

        # Process button
        ttk.Button(options_frame, text="Process File", command=self.process_file).grid(row=1, column=0, columnspan=4, pady=10)

        # Progress bar
        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(file_frame, variable=self.progress_var, mode='indeterminate')
        self.progress_bar.pack(fill=tk.X, padx=10, pady=5)

    def setup_events(self):
        """Setup event bindings."""
        # Real-time encryption/decryption
        self.encrypt_input.bind('<KeyRelease>', self.on_encrypt_change)
        self.decrypt_input.bind('<KeyRelease>', self.on_decrypt_change)

        # Shift change events
        self.encrypt_shift.trace('w', self.on_encrypt_change)
        self.decrypt_shift.trace('w', self.on_decrypt_change)

    def encrypt_text(self):
        """Encrypt text from input field."""
        text = self.encrypt_input.get(1.0, tk.END).strip()
        if not text:
            return

        try:
            shift = self.encrypt_shift.get()
            encrypted = self.cipher.encrypt(text, shift)

            self.encrypt_output.config(state=tk.NORMAL)
            self.encrypt_output.delete(1.0, tk.END)
            self.encrypt_output.insert(1.0, encrypted)
            self.encrypt_output.config(state=tk.DISABLED)

            self.status_var.set(f"Text encrypted with shift {shift}")
        except Exception as e:
            messagebox.showerror("Error", f"Encryption failed: {str(e)}")

    def decrypt_text(self):
        """Decrypt text from input field."""
        text = self.decrypt_input.get(1.0, tk.END).strip()
        if not text:
            return

        try:
            shift = self.decrypt_shift.get()
            decrypted = self.cipher.decrypt(text, shift)

            self.decrypt_output.config(state=tk.NORMAL)
            self.decrypt_output.delete(1.0, tk.END)
            self.decrypt_output.insert(1.0, decrypted)
            self.decrypt_output.config(state=tk.DISABLED)

            self.status_var.set(f"Text decrypted with shift {shift}")
        except Exception as e:
            messagebox.showerror("Error", f"Decryption failed: {str(e)}")

    def auto_decrypt(self):
        """Automatically decrypt using cryptanalysis."""
        text = self.decrypt_input.get(1.0, tk.END).strip()
        if not text:
            messagebox.showwarning("Warning", "Please enter text to decrypt")
            return

        try:
            candidates = self.cipher.auto_decrypt(text, num_candidates=1)
            if candidates:
                shift, decrypted, score = candidates[0]

                self.decrypt_output.config(state=tk.NORMAL)
                self.decrypt_output.delete(1.0, tk.END)
                self.decrypt_output.insert(1.0, decrypted)
                self.decrypt_output.config(state=tk.DISABLED)

                self.decrypt_shift.set(shift)
                self.status_var.set(f"Auto-decrypted with shift {shift} (χ² score: {score:.3f})")
            else:
                messagebox.showinfo("Info", "Unable to determine correct decryption")
        except Exception as e:
            messagebox.showerror("Error", f"Auto-decryption failed: {str(e)}")

    def analyze_all_shifts(self):
        """Analyze text with all possible shifts."""
        text = self.analysis_input.get(1.0, tk.END).strip()
        if not text:
            messagebox.showwarning("Warning", "Please enter text to analyze")
            return

        try:
            # Clear previous results
            for item in self.analysis_tree.get_children():
                self.analysis_tree.delete(item)

            # Perform chi-squared analysis
            results = self.cipher.chi_squared_analysis(text)

            # Store results for detailed view
            self.analysis_results = {}

            for shift, score in results:
                decrypted = self.cipher.decrypt(text, shift)
                preview = decrypted[:50] + ("..." if len(decrypted) > 50 else "")

                # Insert into treeview
                self.analysis_tree.insert('', tk.END, values=(shift, f"{score:.3f}", preview))

                # Store full result
                self.analysis_results[shift] = decrypted

            self.status_var.set(f"Analysis complete - {len(results)} candidates found")
        except Exception as e:
            messagebox.showerror("Error", f"Analysis failed: {str(e)}")

    def frequency_analysis(self):
        """Perform frequency analysis on input text."""
        text = self.analysis_input.get(1.0, tk.END).strip()
        if not text:
            messagebox.showwarning("Warning", "Please enter text to analyze")
            return

        try:
            frequencies = self.cipher.frequency_analysis(text)

            # Create frequency display
            freq_text = "Letter Frequency Analysis:\n\n"
            sorted_freq = sorted(frequencies.items(), key=lambda x: x[1], reverse=True)

            for letter, freq in sorted_freq:
                if freq > 0:
                    freq_text += f"{letter}: {freq:.3f} ({freq*100:.1f}%)\n"

            # Show in detail area
            self.analysis_detail.config(state=tk.NORMAL)
            self.analysis_detail.delete(1.0, tk.END)
            self.analysis_detail.insert(1.0, freq_text)
            self.analysis_detail.config(state=tk.DISABLED)

            self.status_var.set("Frequency analysis complete")
        except Exception as e:
            messagebox.showerror("Error", f"Frequency analysis failed: {str(e)}")

    def on_analysis_select(self, event):
        """Handle selection in analysis results."""
        selection = self.analysis_tree.selection()
        if selection:
            item = self.analysis_tree.item(selection[0])
            shift = int(item['values'][0])

            if shift in self.analysis_results:
                result_text = self.analysis_results[shift]

                self.analysis_detail.config(state=tk.NORMAL)
                self.analysis_detail.delete(1.0, tk.END)
                self.analysis_detail.insert(1.0, f"Shift {shift} result:\n\n{result_text}")
                self.analysis_detail.config(state=tk.DISABLED)

    def on_encrypt_change(self, *args):
        """Handle changes in encrypt tab."""
        # Optional: implement real-time encryption
        pass

    def on_decrypt_change(self, *args):
        """Handle changes in decrypt tab."""
        # Optional: implement real-time decryption
        pass

    def clear_encrypt(self):
        """Clear encryption fields."""
        self.encrypt_input.delete(1.0, tk.END)
        self.encrypt_output.config(state=tk.NORMAL)
        self.encrypt_output.delete(1.0, tk.END)
        self.encrypt_output.config(state=tk.DISABLED)

    def clear_decrypt(self):
        """Clear decryption fields."""
        self.decrypt_input.delete(1.0, tk.END)
        self.decrypt_output.config(state=tk.NORMAL)
        self.decrypt_output.delete(1.0, tk.END)
        self.decrypt_output.config(state=tk.DISABLED)

    def copy_encrypt_result(self):
        """Copy encryption result to clipboard."""
        result = self.encrypt_output.get(1.0, tk.END).strip()
        if result:
            self.root.clipboard_clear()
            self.root.clipboard_append(result)
            self.status_var.set("Result copied to clipboard")

    def browse_input_file(self):
        """Browse for input file."""
        filename = filedialog.askopenfilename(
            title="Select Input File",
            filetypes=[("Text files", "*.txt"), ("All files", "*.*")]
        )
        if filename:
            self.input_file_var.set(filename)

    def browse_output_file(self):
        """Browse for output file."""
        filename = filedialog.asksaveasfilename(
            title="Select Output File",
            defaultextension=".txt",
            filetypes=[("Text files", "*.txt"), ("All files", "*.*")]
        )
        if filename:
            self.output_file_var.set(filename)

    def process_file(self):
        """Process file with Caesar cipher."""
        input_file = self.input_file_var.get()
        output_file = self.output_file_var.get()

        if not input_file or not output_file:
            messagebox.showwarning("Warning", "Please select both input and output files")
            return

        try:
            shift = self.file_shift.get()
            operation = self.file_operation.get()

            # Start progress indication
            self.progress_bar.start()

            # Process file in separate thread to prevent GUI freezing
            def process_thread():
                try:
                    encrypt = (operation == "encrypt")
                    self.cipher.process_file(input_file, output_file, shift, encrypt)

                    # Update GUI from main thread
                    self.root.after(0, lambda: self.file_process_complete(operation, shift))
                except Exception as e:
                    self.root.after(0, lambda: self.file_process_error(str(e)))

            threading.Thread(target=process_thread, daemon=True).start()

        except Exception as e:
            self.progress_bar.stop()
            messagebox.showerror("Error", f"File processing failed: {str(e)}")

    def file_process_complete(self, operation, shift):
        """Handle file processing completion."""
        self.progress_bar.stop()
        self.status_var.set(f"File {operation}ed successfully with shift {shift}")
        messagebox.showinfo("Success", f"File {operation}ed successfully!")

    def file_process_error(self, error_message):
        """Handle file processing error."""
        self.progress_bar.stop()
        self.status_var.set("File processing failed")
        messagebox.showerror("Error", f"File processing failed: {error_message}")

    def export_analysis(self):
        """Export analysis results."""
        if not hasattr(self, 'analysis_results') or not self.analysis_results:
            messagebox.showwarning("Warning", "No analysis results to export")
            return

        filename = filedialog.asksaveasfilename(
            title="Export Analysis Results",
            defaultextension=".json",
            filetypes=[("JSON files", "*.json"), ("All files", "*.*")]
        )

        if filename:
            try:
                self.cipher.export_results(self.analysis_results, filename)
                messagebox.showinfo("Success", f"Results exported to {filename}")
            except Exception as e:
                messagebox.showerror("Error", f"Export failed: {str(e)}")

    def run(self):
        """Start the GUI application."""
        self.root.mainloop()


# Run the application
if __name__ == "__main__":
    app = CaesarCipherGUI()
    app.run()

Outils de cryptanalyse et de rupture

Implémentation d'un décodeur automatisé

Voici une boîte à outils complète de cryptanalyse pour briser les chiffres de César:

import re
import math
from collections import Counter
from typing import List, Dict, Tuple, Optional
import json

class CaesarCryptanalyst:
    """
    Advanced cryptanalysis toolkit for breaking Caesar ciphers.

    Features:
    - Multiple analysis methods
    - Language detection
    - Statistical scoring
    - Dictionary-based validation
    - Automated reporting
    """

    # English letter frequencies (standard reference)
    ENGLISH_FREQ = {
        'A': 8.167, 'B': 1.492, 'C': 2.782, 'D': 4.253, 'E': 12.702,
        'F': 2.228, 'G': 2.015, 'H': 6.094, 'I': 6.966, 'J': 0.153,
        'K': 0.772, 'L': 4.025, 'M': 2.406, 'N': 6.749, 'O': 7.507,
        'P': 1.929, 'Q': 0.095, 'R': 5.987, 'S': 6.327, 'T': 9.056,
        'U': 2.758, 'V': 0.978, 'W': 2.360, 'X': 0.150, 'Y': 1.974,
        'Z': 0.074
    }

    # Common English words for validation
    COMMON_WORDS = {
        'THE', 'AND', 'FOR', 'ARE', 'BUT', 'NOT', 'YOU', 'ALL', 'CAN', 'HER',
        'WAS', 'ONE', 'OUR', 'HAD', 'BY', 'HIS', 'IS', 'IT', 'AN', 'AS',
        'THAT', 'HAVE', 'FROM', 'OR', 'OF', 'TO', 'IN', 'BEEN', 'HAS',
        'WERE', 'SAID', 'EACH', 'WHICH', 'THEIR', 'TIME', 'WILL', 'ABOUT',
        'IF', 'UP', 'OUT', 'MANY', 'THEN', 'THEM', 'THESE', 'SO', 'SOME',
        'HE', 'SHE', 'WE', 'BE', 'MY', 'AT', 'WITH', 'ON', 'DO', 'NO'
    }

    # Bigram frequencies for enhanced analysis
    ENGLISH_BIGRAMS = {
        'TH': 3.882543, 'HE': 3.681391, 'IN': 2.283899, 'ER': 2.178042,
        'AN': 2.971208, 'ED': 1.53346, 'ND': 1.632781, 'TO': 1.693717,
        'EN': 1.383239, 'TI': 1.636312, 'ES': 1.159737, 'OR': 1.053385,
        'TE': 1.200944, 'OF': 1.056429, 'BE': 1.058438, 'HA': 1.018601,
        'AR': 0.975560, 'OU': 0.920865, 'AS': 0.860210, 'AT': 0.751699
    }

    def __init__(self, custom_dictionary: Optional[List[str]] = None):
        """
        Initialize cryptanalyst with optional custom dictionary.

        Args:
            custom_dictionary: Additional words for validation
        """
        self.dictionary = self.COMMON_WORDS.copy()
        if custom_dictionary:
            self.dictionary.update(word.upper() for word in custom_dictionary)

    def analyze_frequency(self, text: str) -> Dict[str, float]:
        """
        Calculate letter frequencies as percentages.

        Args:
            text: Text to analyze

        Returns:
            Dictionary mapping letters to frequency percentages
        """
        # Clean text (alphabetic characters only, uppercase)
        clean_text = ''.join(c.upper() for c in text if c.isalpha())

        if not clean_text:
            return {}

        total_letters = len(clean_text)
        letter_counts = Counter(clean_text)

        # Convert to percentages
        frequencies = {}
        for letter in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
            count = letter_counts.get(letter, 0)
            frequencies[letter] = (count / total_letters) * 100

        return frequencies

    def chi_squared_score(self, observed_freq: Dict[str, float]) -> float:
        """
        Calculate chi-squared statistic comparing observed vs expected frequencies.

        Args:
            observed_freq: Observed letter frequencies (as percentages)

        Returns:
            Chi-squared score (lower is better match to English)
        """
        chi_squared = 0.0

        for letter in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
            observed = observed_freq.get(letter, 0.0)
            expected = self.ENGLISH_FREQ[letter]

            if expected > 0:
                chi_squared += ((observed - expected) ** 2) / expected

        return chi_squared

    def index_of_coincidence(self, text: str) -> float:
        """
        Calculate Index of Coincidence for the text.

        Args:
            text: Text to analyze

        Returns:
            Index of Coincidence value
        """
        # Clean text
        clean_text = ''.join(c.upper() for c in text if c.isalpha())
        n = len(clean_text)

        if n < 2:
            return 0.0

        # Count letter frequencies
        letter_counts = Counter(clean_text)

        # Calculate IC using the formula: Σ(ni(ni-1)) / (N(N-1))
        ic_sum = sum(count * (count - 1) for count in letter_counts.values())
        ic = ic_sum / (n * (n - 1))

        return ic

    def bigram_analysis(self, text: str) -> Dict[str, float]:
        """
        Analyze bigram (2-letter combination) frequencies.

        Args:
            text: Text to analyze

        Returns:
            Dictionary of bigram frequencies
        """
        clean_text = ''.join(c.upper() for c in text if c.isalpha())

        if len(clean_text) < 2:
            return {}

        bigrams = [clean_text[i:i+2] for i in range(len(clean_text) - 1)]
        total_bigrams = len(bigrams)

        if total_bigrams == 0:
            return {}

        bigram_counts = Counter(bigrams)

        # Convert to percentages
        bigram_freq = {}
        for bigram, count in bigram_counts.items():
            bigram_freq[bigram] = (count / total_bigrams) * 100

        return bigram_freq

    def dictionary_score(self, text: str) -> float:
        """
        Score text based on number of valid English words found.

        Args:
            text: Text to score

        Returns:
            Percentage of words found in dictionary
        """
        # Extract words (sequences of alphabetic characters)
        words = re.findall(r'[A-Za-z]+', text.upper())

        if not words:
            return 0.0

        valid_words = sum(1 for word in words if word in self.dictionary)
        return (valid_words / len(words)) * 100

    def composite_score(self, text: str) -> float:
        """
        Calculate composite score combining multiple analysis methods.

        Args:
            text: Text to score

        Returns:
            Composite score (higher is better)
        """
        if not text.strip():
            return 0.0

        # Calculate individual scores
        freq_analysis = self.analyze_frequency(text)
        chi_squared = self.chi_squared_score(freq_analysis)
        ic_score = self.index_of_coincidence(text)
        dict_score = self.dictionary_score(text)

        # Normalize and combine scores
        # Lower chi-squared is better, so invert it
        normalized_chi = max(0, 100 - chi_squared)

        # IC for English is approximately 0.067, so score based on closeness
        ic_target = 0.067
        ic_normalized = max(0, 100 - abs(ic_score - ic_target) * 1000)

        # Weighted combination
        composite = (
            normalized_chi * 0.4 +  # 40% weight on frequency analysis
            ic_normalized * 0.3 +   # 30% weight on IC
            dict_score * 0.3        # 30% weight on dictionary words
        )

        return composite

    def caesar_breaker(self, ciphertext: str, num_results: int = 5) -> List[Dict]:
        """
        Comprehensive Caesar cipher breaking with multiple analysis methods.

        Args:
            ciphertext: Encrypted text to analyze
            num_results: Number of best results to return

        Returns:
            List of analysis results sorted by quality
        """
        results = []

        for shift in range(26):
            # Decrypt with current shift
            decrypted = self._apply_shift(ciphertext, -shift)

            # Calculate various scores
            freq_analysis = self.analyze_frequency(decrypted)
            chi_squared = self.chi_squared_score(freq_analysis)
            ic_score = self.index_of_coincidence(decrypted)
            dict_score = self.dictionary_score(decrypted)
            composite = self.composite_score(decrypted)

            # Create result entry
            result = {
                'shift': shift,
                'decrypted_text': decrypted,
                'chi_squared': chi_squared,
                'index_of_coincidence': ic_score,
                'dictionary_score': dict_score,
                'composite_score': composite,
                'frequency_analysis': freq_analysis
            }

            results.append(result)

        # Sort by composite score (descending)
        results.sort(key=lambda x: x['composite_score'], reverse=True)

        return results[:num_results]

    def _apply_shift(self, text: str, shift: int) -> str:
        """
        Apply Caesar cipher shift to text.

        Args:
            text: Text to shift
            shift: Shift amount

        Returns:
            Shifted text
        """
        result = []

        for char in text:
            if char.isalpha():
                base = ord('A') if char.isupper() else ord('a')
                shifted = (ord(char) - base + shift) % 26
                result.append(chr(shifted + base))
            else:
                result.append(char)

        return ''.join(result)

    def detailed_analysis_report(self, ciphertext: str, output_file: Optional[str] = None) -> str:
        """
        Generate detailed cryptanalysis report.

        Args:
            ciphertext: Text to analyze
            output_file: Optional file to save report

        Returns:
            Formatted analysis report
        """
        print("Performing comprehensive Caesar cipher analysis...")

        # Get analysis results
        results = self.caesar_breaker(ciphertext, num_results=10)

        # Build report
        report = []
        report.append("=" * 80)
        report.append("CAESAR CIPHER CRYPTANALYSIS REPORT")
        report.append("=" * 80)
        report.append(f"\nOriginal Ciphertext ({len(ciphertext)} characters):")
        report.append("-" * 50)
        report.append(ciphertext[:200] + ("..." if len(ciphertext) > 200 else ""))

        # Overall statistics
        report.append(f"\nCiphertext Statistics:")
        report.append("-" * 30)

        original_ic = self.index_of_coincidence(ciphertext)
        report.append(f"Index of Coincidence: {original_ic:.6f}")

        letter_count = sum(1 for c in ciphertext if c.isalpha())
        report.append(f"Alphabetic characters: {letter_count}")

        # Top candidates
        report.append(f"\nTop Decryption Candidates:")
        report.append("-" * 40)

        for i, result in enumerate(results, 1):
            report.append(f"\n{i}. Shift {result['shift']:2d} (Score: {result['composite_score']:.2f})")
            report.append(f"   χ² = {result['chi_squared']:.3f}, IC = {result['index_of_coincidence']:.6f}, Dict = {result['dictionary_score']:.1f}%")

            preview = result['decrypted_text'][:100]
            if len(result['decrypted_text']) > 100:
                preview += "..."
            report.append(f"   Preview: {preview}")

        # Detailed analysis of best candidate
        if results:
            best = results[0]
            report.append(f"\nDetailed Analysis - Best Candidate (Shift {best['shift']}):")
            report.append("-" * 50)

            # Full decrypted text
            report.append(f"\nComplete Decrypted Text:")
            report.append(best['decrypted_text'])

            # Frequency analysis
            report.append(f"\nLetter Frequency Analysis:")
            sorted_freq = sorted(best['frequency_analysis'].items(),
                               key=lambda x: x[1], reverse=True)

            for letter, freq in sorted_freq:
                expected = self.ENGLISH_FREQ[letter]
                diff = freq - expected
                report.append(f"  {letter}: {freq:5.2f}% (expected {expected:5.2f}%, diff {diff:+5.2f}%)")

        report_text = "\n".join(report)

        # Save to file if requested
        if output_file:
            with open(output_file, 'w', encoding='utf-8') as f:
                f.write(report_text)
            print(f"Report saved to: {output_file}")

        return report_text

    def interactive_analysis(self):
        """
        Interactive command-line cryptanalysis tool.
        """
        print("=== Interactive Caesar Cipher Cryptanalyst ===")
        print("Enter 'help' for commands, 'quit' to exit")

        while True:
            try:
                command = input("\nCryptanalyst> ").strip().lower()

                if command == 'quit':
                    print("Goodbye!")
                    break
                elif command == 'help':
                    self._show_help()
                elif command.startswith('analyze '):
                    ciphertext = command[8:]
                    if ciphertext:
                        results = self.caesar_breaker(ciphertext, num_results=3)
                        self._display_results(results)
                    else:
                        print("Usage: analyze <ciphertext>")
                elif command.startswith('report '):
                    ciphertext = command[7:]
                    if ciphertext:
                        report = self.detailed_analysis_report(ciphertext)
                        print(report)
                    else:
                        print("Usage: report <ciphertext>")
                else:
                    print(f"Unknown command: {command}")
                    print("Type 'help' for available commands")

            except KeyboardInterrupt:
                print("\nGoodbye!")
                break
            except Exception as e:
                print(f"Error: {e}")

    def _show_help(self):
        """Display help information."""
        help_text = """
Available Commands:
  analyze <text>  - Quick analysis of ciphertext
  report <text>   - Detailed analysis report
  help           - Show this help message
  quit           - Exit the program

Example:
  analyze KHOOR ZRUOG
  report WKH TXLFN EURZQ IRA
        """
        print(help_text)

    def _display_results(self, results: List[Dict]):
        """Display analysis results in formatted table."""
        print(f"\n{'Rank':<4} {'Shift':<5} {'Score':<6} {'χ²':<8} {'Dict%':<6} {'Preview':<30}")
        print("-" * 65)

        for i, result in enumerate(results, 1):
            preview = result['decrypted_text'][:30].replace('\n', ' ')
            print(f"{i:<4} {result['shift']:<5} {result['composite_score']:<6.1f} "
                  f"{result['chi_squared']:<8.3f} {result['dictionary_score']:<6.1f} {preview}")


# Demonstration and testing
def main():
    """Demonstrate cryptanalysis capabilities."""

    # Initialize cryptanalyst
    analyst = CaesarCryptanalyst()

    # Test cases
    test_cases = [
        ("KHOOR ZRUOG", "Simple greeting"),
        ("WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ", "Classic pangram"),
        ("FDHVDU FLSKHU LV RQH RI WKH HDULHVW NQRZQ DQG VLPSOHVW FLSKHUV", "Description text")
    ]

    print("=== Caesar Cipher Cryptanalysis Demo ===")

    for ciphertext, description in test_cases:
        print(f"\n{description}: {ciphertext}")
        print("-" * 60)

        results = analyst.caesar_breaker(ciphertext, num_results=3)

        for i, result in enumerate(results, 1):
            print(f"{i}. Shift {result['shift']:2d} (Score: {result['composite_score']:.1f}): "
                  f"{result['decrypted_text']}")

    # Interactive mode option
    print(f"\n=== Interactive Mode Available ===")
    print("To start interactive analysis, call: analyst.interactive_analysis()")


if __name__ == "__main__":
    main()

Conclusion

Ce didacticiel complet sur le chiffrement Python Caesar fournit des implémentations complètes depuis les fonctions de base jusqu'aux applications de qualité professionnelle avec des interfaces GUI et des capacités avancées de cryptanalyse. La progression de simples fonctions de chiffrement vers des outils sophistiqués démontre la polyvalence de Python pour l'enseignement cryptographique et les applications pratiques de sécurité.

Réalisations clés en matière d'apprentissage:

  1. Mise en œuvre fondamentale: Maîtrisez les algorithmes de base du chiffrement César avec une gestion appropriée des erreurs et une gestion des cas extrêmes.
  2. Fonctionnalités avancées: implémentez des cours de niveau professionnel avec gestion de la configuration, traitement des fichiers et optimisation des performances
  3. Développement d'interface graphique: créez des applications conviviales à l'aide de Tkinter pour le cryptage et l'analyse interactifs
  4. Compétences en cryptanalyse: développer des outils automatisés pour briser les chiffres de César à l'aide de l'analyse statistique et de la reconnaissance de formes
  5. Bonnes pratiques: appliquer les normes de codage, la documentation, les tests et les pratiques professionnelles de développement de logiciels Python.

Applications pratiques:

  • Outils pédagogiques: applications d'apprentissage interactives pour l'enseignement de la cryptographie
  • Évaluation de la sécurité: outils pour analyser les implémentations de chiffrement classique dans les systèmes existants
  • Formation en programmation: exemples complets illustrant plusieurs concepts et bibliothèques Python
  • Applications de recherche: cadres extensibles pour la recherche et le développement d'algorithmes cryptographiques

Les exemples complets de code source fournissent des implémentations immédiatement utilisables, adaptées à l'apprentissage, à l'enseignement et au développement d'applications pratiques. Chaque implémentation comprend une documentation détaillée, une gestion des erreurs et des fonctionnalités d'extensibilité qui prennent en charge à la fois l'utilisation pédagogique et le développement professionnel.

Prochaines étapes pour un apprentissage continu:

  • Explorez des chiffres classiques plus sophistiqués comme Vigenère et Playfair
  • Étudier les algorithmes et implémentations cryptographiques modernes
  • Étudier les techniques avancées de cryptanalyse et les méthodes d’analyse statistique
  • Développer des applications Web à l'aide des frameworks Flask ou Django
  • Contribuer aux bibliothèques cryptographiques open source et aux ressources pédagogiques

N'oubliez pas: bien que les chiffres César n'offrent aucune sécurité dans les applications modernes, ils offrent d'excellentes bases pour comprendre les principes cryptographiques, la mise en œuvre des algorithmes et les méthodologies d'analyse de sécurité qui s'appliquent aux systèmes cryptographiques et aux pratiques de sécurité contemporaines.

Référentiel complet de code source

Tous les exemples de code source de ce didacticiel sont disponibles dans un référentiel GitHub structuré avec des ressources supplémentaires, des exemples étendus et une documentation complète. Le référentiel comprend:

  • Implémentations de base avec commentaires détaillés et exercices d'apprentissage
  • Fonctionnalités avancées, y compris des tests de performances et des techniques d'optimisation\
  • Applications GUI avec code source complet et instructions d'installation
  • Outils de cryptanalyse dotés de capacités d'analyse statistique étendues
  • Modèles de projets pour les devoirs pédagogiques et les applications pratiques
  • Suites de tests avec des cas de test complets et des exemples de validation

Accédez à la collection complète sur: Python Caesar Cipher Tutorial Repository avec des mises à jour régulières, des contributions de la communauté et un soutien continu pour les apprenants et les enseignants du monde entier.

À propos de cet article

Cet article fait partie de notre collection de guides Chiffre César. Explorez les outils, exemples et workflows pratiques associés sur CaesarCipher.org.

Autres Tutoriels Chiffre César

Essayez l'outil Chiffre César

Mettez le guide en pratique avec des outils et exemples liés à chiffre césar.

Essayez l'outil Chiffre César