2012-06-22 2 views
1

Я хотел бы построить cypher с python, который расшифровывает текст, многократно перемещаясь по номерам переключателя слева направо, а затем справа налево и сдвигая букву в алфавите на соответствующий номер.Python cypher: как построить сложную систему переключения?

Пример:

  • переключения: 123
  • текст: i like python
  • процесс: + 1 = у, пространство, L + 2 = п, г + 3 = л, к + 3 = n, e + 2 = g, пробел, p + 1 = q, y + 1 = z, t + 2 = v, h + 3 = j, o + 3 = q, n + 2 = p
  • результат: j nlng qzvjqp

код до сих пор:

import string 

numbers = "" 

x = 3 

while x < 10000: 
    numbers = numbers + str(x) 
    x += 1 

shift = 221 

#string.ascii_lowercase 
letters = string.ascii_letters + string.punctuation + numbers 
text = (raw_input("Please enter text")) 

encoded = '' 
for letter in text: 
    if letter == ' ': 
     encoded = encoded + ' ' 
    else: 
     x = letters.index(letter) + shift 
     encoded = encoded + letters[x] 

print encoded 

Он использует до сих пор базовый метод кодирования. Мне было бы интересно узнать, как можно реализовать описанную выше систему кодирования в коде.

+3

Предупреждение, что этот шифр крайне небезопасен. – Sean

+1

Альтернативой будет RC4. Это простой, но мощный потоковый шифр. [Здесь] (https://gist.github.com/2958701) является реализацией Python. – schlamar

+2

Я скопировал ваш код на вопрос, чтобы избежать дополнительного нажатия. – georg

ответ

2

Вот ваша версия оптимизирована (и работа):

import string 

shift = 221 

letters = string.ascii_letters + string.punctuation + string.digits 
text = raw_input("Please enter text\n") 

e = ''.join(letters[letters.index(l) + shift % len(letters)] 
      if letters.index(l) is not None else ' ' for l in text) 
print e 

Редактировать Части с номерами было действительно так, потому что он добавил повторяющиеся буквы в вашу последовательность кодирования. Это означает, что кодированный текст не может быть декодирован однозначно.

Редактировать2: Если вы хотите безопасное en/decryption, вам нужен современный алгоритм, такой как AES. Если вы хотите, чтобы он реализовывался самостоятельно или понимал код, RC4 - простая (но все же безопасная, если используется правильно) альтернатива.

Edit3: Вот Vigenere в оптимизированной версии:

from itertools import cycle, izip 
from operator import add, sub 
from string import printable as alphabet 

def vigenere(text, key, mode='encode'): 
    alen = len(alphabet) 
    key = cycle(key + key[-2:0:-1]) 
    op = add if mode == 'encode' else sub 
    return ''.join(alphabet[op(alphabet.index(c), 
           alphabet.index(k)) % alen] 
        for c, k in izip(text, key)) 

c = vigenere('attack at dawn', 'secret', mode='encode') 
print c # CHFBqN8BF8FoIO 
print vigenere(c, 'secret', mode='decode') 
+1

Это Цезарь, и он хочет, чтобы Vigenere (= разные смены для разных буквы) с дополнительным требованием «маятника». – georg

+0

@ thg435 О, действительно. Его код был шифром Цезаря, хотя :) – schlamar

+1

@ thg435 Добавил мою собственную реализацию Vigenere – schlamar

1

Просто для удовольствия вот (намеренно многословно) vigenere реализация с "маятником" ключ:

def pendulum(s): 
    """Given abcd yields abcdcbabcdc... """ 
    while True: 
     for p in s: yield p 
     for p in reversed(s[1:-1]): yield p 


def vigenere(text, key, mode='encode'): 
    alphabet = 'abcdefghijklmnopqrstuvwxyz ' 
    key = pendulum(key) 
    encoded = '' 

    for char in text: 
     index = alphabet.index(char) 
     offset = alphabet.index(next(key)) 

     if mode == 'encode': 
      shifted = index + offset 
     else: 
      shifted = index - offset 

     encoded += alphabet[shifted % len(alphabet)] 
    return encoded 

# test 

print vigenere('attack at dawn', 'secret', mode='encode') # sxvrgcdrvdveyd 
print vigenere('sxvrgcdrvdveyd', 'secret', mode='decode') 

Пусть нам знаете, если у вас есть вопросы.

+0

Не использовать '%' для 'shifted' слишком многословно ... – schlamar

+0

@ ms4py: показать мне, как! – georg

+1

'закодировано + = алфавит [shifted% alen]' – schlamar

Смежные вопросы