Academy / Klassik / Vigenère Shifri

Vigenère Shifri

Klassik O'rta

Vigenère shifri nima?

Blaise de Vigenère tomonidan yaratilgan (XVI asr). Caesar shifrini kuchaytiradi: har harfni boshqacha kalit bilan siljitadi.

💡 Asosiy farq

Caesar: bitta kalit → bitta siljish
Vigenère: kalit so'z → har harf uchun turli siljish

Qanday ishlaydi?

def vigenere_encrypt(plaintext: str, key: str) -> str:
    result = []
    key = key.upper()
    key_index = 0
    
    for char in plaintext.upper():
        if char.isalpha():
            # Kalit harfini siljish sifatida ishlat
            shift = ord(key[key_index % len(key)]) - ord('A')
            shifted = (ord(char) - ord('A') + shift) % 26
            result.append(chr(shifted + ord('A')))
            key_index += 1
        else:
            result.append(char)
    
    return ''.join(result)

def vigenere_decrypt(ciphertext: str, key: str) -> str:
    result = []
    key = key.upper()
    key_index = 0
    
    for char in ciphertext.upper():
        if char.isalpha():
            shift = ord(key[key_index % len(key)]) - ord('A')
            shifted = (ord(char) - ord('A') - shift) % 26  # Ayirish!
            result.append(chr(shifted + ord('A')))
            key_index += 1
        else:
            result.append(char)
    
    return ''.join(result)

# Misol
matn = "HELLO WORLD"
kalit = "KEY"
encrypted = vigenere_encrypt(matn, kalit)
print("Shifrlangan:", encrypted)  # RIJVS UYVJN

decrypted = vigenere_decrypt(encrypted, kalit)
print("Deshifrlangan:", decrypted)  # HELLO WORLD

Kasiski testi — Vigenèreни buzish

1
Takrorlanuvchi 3+ harfli ketma-ketliklarni toping
2
Ular orasidagi masofani o'lchang
3
GCD(masofalar) = kalit uzunligi
4
Har kalit pozitsiyasi uchun alohida Caesar
from math import gcd
from functools import reduce
from collections import Counter

def kasiski_test(ciphertext: str, min_len: int = 3) -> list:
    # Takrorlanuvchi ketma-ketliklarni toping va GCD hisoblang
    ct = ''.join(c for c in ciphertext.upper() if c.isalpha())
    spacings = []
    
    for length in range(min_len, 6):
        for i in range(len(ct) - length):
            pattern = ct[i:i+length]
            for j in range(i + length, len(ct) - length + 1):
                if ct[j:j+length] == pattern:
                    spacings.append(j - i)
    
    if not spacings:
        return []
    
    # GCD hisoblash
    overall_gcd = reduce(gcd, spacings)
    factors = [i for i in range(2, 20) if overall_gcd % i == 0]
    return factors

def find_key_length(ciphertext: str) -> int:
    factors = kasiski_test(ciphertext)
    return factors[0] if factors else 1

# Kalit uzunligi topilgandan keyin har pozitsiyani Caesar kabi hal qilish
def break_vigenere(ciphertext: str, key_length: int) -> str:
    ct = ''.join(c for c in ciphertext.upper() if c.isalpha())
    key = ""
    
    for i in range(key_length):
        # Har i-chi pozitsiyasidagi harflarni to'pla
        column = ct[i::key_length]
        # Eng ko'p uchragan harf E ga mos kelishi kerak
        freq = Counter(column).most_common(1)[0][0]
        shift = (ord(freq) - ord('E')) % 26
        key += chr(shift + ord('A'))
    
    return key
← Caesar Shifri RSA Kriptografiyasi →

💡 Bu mavzu bo'yicha amaliy mashq qilishni istaysizmi?

Klassik challengelarini ko'rish →