Как реализовать шифрование с использованием шифра Виженера на языке Python?

<b>Здравствуйте! </b> <br/> Я студент информационной безопасности в АмГУ, и недавно нам задали лабораторные работы, связанные с расшифровкой и шифрованием слов. <br/> <br/> <b>К сожалению, </b> за три года обучения нас этому так и не научили. Преподаватели сказали, что можно использовать Excel или любой язык программирования, если кто-то в этом разбирается. <br/> <br/> Я решил выполнить задание на Python, и у меня возник вопрос: как мне зашифровать текст? <br/> <br/> У меня уже есть код для расшифровки: <br/> <pre><code class="python">import alfavit
from alfavit import alfa

slovo = [21, 1, 3, 1, 20, 24, 29]
g=0
gg=0
N=33
for i in alfa:
    print(f"Начало. Ключ {gg}", end="\n")
    for i in slovo:
        a=(slovo[g] - (0+gg))%N
        print(alfa[a], end="")
        g=g+1
    print(" ", end="\n")
    print("конец")
    g=0
    gg=gg+1</code></pre> <br/> <br/> Файл alfavit.py содержит определение алфавита в списке alfa=["а", "б", "...]. <br/> <br/> У меня вроде всё готово, но я не могу разобраться с шифрованием. Вот набросок кода: <br/> <pre><code class="python">import alfavit
from alfavit import alfa

slovo=input("Введите текст слитно ")
S=int(input("Введите длину ключа (до 32) "))
N=32
g=0
 
for i in slovo:
    c=(slovo[g]+S)%N
    print(c)
    g=g+1</code></pre> <br/> <br/> Мне нужно, чтобы текст, введенный пользователем, разбивался на отдельные буквы, затем каждая буква сравнивалась с алфавитом alfa, после чего буквы преобразовывались в цифры по их порядковому номеру в списке alfa. Затем этим числом можно будет уже шифровать. <br/> Я искал информацию в интернете, но там в основном объясняются функции, и понять ничего не удалось, поэтому я решил обратиться за помощью.
  • 30 октября 2024 г. 8:33
Ответы на вопрос 2
Здравствуйте! Давайте реализуем шифрование с использованием шифра Виженера на Python. Шифр Виженера работает на основе симметричного шифрования, где ключ повторяется для шифрования текста. Мы можем сделать это в несколько шагов:

1. **Преобразуем буквы в их порядковые номера** (индексы в алфавите).
2. **Шифруем текст, используя ключ**.
3. **Превращаем зашифрованные индексы обратно в буквы**.

Вот как это можно реализовать:

```python
import alfavit
from alfavit import alfa

def text_to_indexes(text):
    """Преобразуем текст в индексы согласно алфавиту."""
    return [alfa.index(char) for char in text if char in alfa]

def indexes_to_text(indexes):
    """Преобразуем индексы обратно в текст."""
    return ''.join(alfa[i] for i in indexes)

def vigenere_encrypt(plaintext, key):
    """Шифровка текста с использованием шифра Виженера."""
    plaintext_indexes = text_to_indexes(plaintext)  # Преобразуем текст в индексы
    key_indexes = text_to_indexes(key)  # Преобразуем ключ в индексы

    encrypted_indexes = []
    key_length = len(key_indexes)

    for i, index in enumerate(plaintext_indexes):
        key_index = key_indexes[i % key_length]  # Повторяем ключ
        encrypted_indexes.append((index + key_index) % len(alfa))  # Шифрование

    return indexes_to_text(encrypted_indexes)  # Преобразуем индексы обратно в текст

# Пример использования
if __name__ == "__main__":
    plaintext = input("Введите текст слитно: ")
    key = input("Введите ключ: ")

    encrypted_text = vigenere_encrypt(plaintext, key)
    print("Зашифрованный текст:", encrypted_text)
```

### Объяснение кода:

1. **Функция `text_to_indexes`**: Эта функция принимает текст и возвращает список индексов букв, где каждая буква соответствует ее позиции в списке `alfa`.

2. **Функция `indexes_to_text`**: Эта функция делает обратное, принимая список индексов и возвращая соответствующий текст.

3. **Функция `vigenere_encrypt`**: Основная логика для шифрования. Здесь:
   - У нас есть входной текст и ключ.
   - Мы преобразуем оба в индексы.
   - Для каждого символа в исходном тексте мы добавляем соответствующий символ из ключа (соблюдая модуль длины алфавита) и сохраняем результат.

### Зависимости:
- Обратите внимание, что в коде предполагается, что ваш файл `alfavit.py` имеет правильный список `alfa`, содержащий все буквы алфавита, в том числе пробелы, если они необходимы.

Используя этот код, вы сможете зашифровать текст с помощью шифра Виженера. Если у вас есть еще вопросы, не стесняйтесь спрашивать!
Делишь задачу на под-задачи. Допустим, у тебя есть строка-исходный текст text и строка-ключ key , а также список строк, содержащий алфавит языка alpha . 
Определяешь функцию, заменяющую символ по шифру:
# принимает символ открытого текста, его позицию в тексте, строку-ключ и алфавит
# возвращаем символ шифротекста
def viginere_encode(text_char: str, i: int, key: str, alpha: list[str]) -> str:
  if text_char not in alpha:  # незнакомый символ?
    return text_char  # оставляем его как есть
  text_char_code = alpha.index(text_char)  # номер символа открытого текста в алфавите
  key_char = key[i % len(key)]  # символ ключа, соответствующего i-му символу открытого текста 
  key_char_code = alpha.index(key_char)   # номер символа ключа в алфавите
  cypher_char_code = (text_char_code + key_char_code) % len(alpha)  # номер символа шифротекста
  return alpha[cypher_char_code]  # возвращаем символ шифротекста

А дальше применяем эту функцию к строке:
cipher_text = ''
for i in range(len(text)):
  cipher_text += viginere_encode(text[i], i, key, alpha)

Вот и всё. Да, тут много чего можно оптимизировать, но я старался писать как можно проще.

Похожие вопросы