2013-05-11 2 views
1

Итак, я пишу код шифрования на основе python. Код был длиннее, чем нужно, поэтому я переключил его часть на функции. Как только я начал это делать, он сказал, что не может найти переменные. Чтобы исправить это, я установил переменные как глобальные. Тем не менее, он по-прежнему не будет работать, и дает мне ошибку:Функция шифрования Python и глобальные переменные

Traceback (most recent call last): 
    File "C:/Users/Alex/Desktop/Encryptor.py", line 272, in <module> 
    startup() 
    File "C:/Users/Alex/Desktop/Encryptor.py", line 257, in startup 
    encrypt() 
    File "C:/Users/Alex/Desktop/Encryptor.py", line 44, in encrypt 
    maincrypt(2) 
    File "C:/Users/Alex/Desktop/Encryptor.py", line 12, in maincrypt 
    print newtext 
UnboundLocalError: local variable 'newtext' referenced before assignment 

Вот мой код:

letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] 
def maincrypt(num): 
    print otext 
    print textlist 
    print newtextlist 
    print newtext 
    print times 
    print i 
    add = times + num 
    while add > 25: 
     add = add - 25 
     if ord(i) >= 65 and ord(i) <= 90: 
      newtext += letters[add].uppercase 
     else: 
      newtext += letters[add] 
def encrypt(): 
    global otext 
    global textlist 
    global newtextlist 
    global newtext 
    global times 
    global i 
    otext = raw_input("Text?") 
    textlist = [] 
    newtextlist = [] 
    newtext= "" 
    times = 0 
    for i in otext: 
     textlist.append(i) 
    for i in textlist: 
     if i == 'a' or i == 'A': 
      maincrypt(0) 
     elif i == 'b' or i == 'B': 
      maincrypt(1) 
     elif i == 'c' or i == 'C': 
      maincrypt(2) 
     elif i == 'd' or i == 'D': 
      maincrypt(3) 
     elif i == 'e' or i == 'E': 
      maincrypt(4) 
     elif i == 'f' or i == 'F': 
      maincrypt(5) 
     elif i == 'g' or i == 'G': 
      maincrypt(6) 
     elif i == 'h' or i == 'H': 
      maincrypt(7) 
     elif i == 'i' or i == 'I': 
      maincrypt(8) 
     elif i == 'j' or i == 'J': 
      maincrypt(9) 
     elif i == 'k' or i == 'K': 
      maincrypt(10) 
     elif i == 'l' or i == 'L': 
      maincrypt(11) 
     elif i == 'm' or i == 'M': 
      maincrypt(12) 
     elif i == 'n' or i == 'N': 
      maincrypt(13) 
     elif i == 'o' or i == 'O': 
      maincrypt(14) 
     elif i == 'p' or i == 'P': 
      maincrypt(15) 
     elif i == 'q' or i == 'Q': 
      maincrypt(16) 
     elif i == 'r' or i == 'R': 
      maincrypt(17) 
     elif i == 's' or i == 'S': 
      maincrypt(18) 
     elif i == 't' or i == 'T': 
      maincrypt(19) 
     elif i == 'u' or i == 'U': 
      maincrypt(20) 
     elif i == 'v' or i == 'V': 
      maincrypt(21) 
     elif i == 'w' or i == 'W': 
      maincrypt(22) 
     elif i == 'x' or i == 'X': 
      maincrypt(23) 
     elif i == 'y' or i == 'Y': 
      maincrypt(24) 
     elif i == 'z' or i == 'Z': 
      maincrypt(25) 
     else: 
      newtext += i 
     times += 1 
    print newtext 

def decrypt(): 
    otext = raw_input("Text?") 
    textlist = [] 
    newtextlist = [] 
    newtext= "" 
    times = 0 
    for i in otext: 
     textlist.append(i) 
    for i in textlist: 
     if i == 'a' or i == 'A': 
      add = 0 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'b' or i == 'B': 
      add = 1 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'c' or i == 'C': 
      add = 2 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'd' or i == 'D': 
      add = 3 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'e' or i == 'E': 
      add = 4 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'f' or i == 'F': 
      add = 5 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'g' or i == 'G': 
      add = 6 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'h' or i == 'H': 
      add = 7 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'i' or i == 'I': 
      add = 8 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'j' or i == 'J': 
      add = 9 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'k' or i == 'K': 
      add = 10 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'l' or i == 'L': 
      add = 11 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'm' or i == 'M': 
      add = 12 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'n' or i == 'N': 
      add = 13 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'o' or i == 'O': 
      add = 14 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'p' or i == 'P': 
      add = 15 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'q' or i == 'Q': 
      add = 16 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'r' or i == 'R': 
      add = 17 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 's' or i == 'S': 
      add = 18 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 't' or i == 'T': 
      add = 19 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'u' or i == 'U': 
      add = 20 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'v' or i == 'V': 
      add = 21 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'w' or i == 'W': 
      add = 22 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'x' or i == 'X': 
      add = 23 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'y' or i == 'Y': 
      add = 24 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     elif i == 'z' or i == 'Z': 
      add = 25 - times 
      while add < 0: 
       add = add + 25 
      newtext += letters[add] 
     else: 
      newtext += i 
     times += 1 
    print newtext 

def startup(): 
    upass = raw_input("Password: ") 
    if upass == "astrocrypt": 
     print """Welcome! 
1: Encrypt 
2: Decrypt 
3: Credits 
4: Quit""" 
     try: 
      choice = input() 
     except SyntaxError: 
      print "Oops! That's not a valid number! Try again!" 
      startup() 
     except NameError: 
      print "Oops! That's not a valid number! Try again!" 
      startup() 
     if choice == 1: 
      encrypt() 
      startup() 
     elif choice == 2: 
      decrypt() 
      startup() 
     elif choice == 3: 
      print "Made by Alex Taber" 
      startup() 
     elif choice == 4: 
      pass 
     else: 
      print "Unknown number" 
      startup() 
    else: 
     print "Incorrect password!" 
startup() 
+1

У меня есть предложение. Вместо цепей if/elif, выполните ord (i.upper()) - ord ('A'). Это даст вам 0 для a/A, 1 для b/B, 2 для c/C и т. Д. (Http://docs.python.org/2/library/functions.html#ord) – Patashu

+0

Умный фрагмент кода , хотя это не решает мою проблему. В любом случае, это похоже на обман, если я этого не понимаю = P – astronautlevel

+0

Конечно, я объясню это вам - ord ('A') - 65, ord ('B') - 66 и так далее. ord ('a') составляет 97 - 32 выше 65. ord ('b') - 98 и т. д. (http://www.asciitable.com/index/asciifull.gif показывает порядок). Так что, если я вычитаю ord (i) в ord ('A'), где i является капитальным символом, я получаю, что такое позиция алфавита. Поэтому, если я вычитаю ord (i.upper()) в ord ('A'), где i является символом капитала или нижнего регистра, я получаю, что это за алфавит. – Patashu

ответ

2

Чтобы защитить программист от глобал, Глобал не считается не существует в функции до тех пор, вы заявляете, что они делают с global variablename. В maincrypt вы не объявляете global newtext и не создаете локальный newtext, назначив ему. Оператор + = требует, чтобы левая рука уже существовала - этого еще нет, поэтому генерируется исключение.

Кстати, если вы планируете повторно использовать эту программу в другом месте, лучше использовать переменные класса вместо globals, поэтому 1) если кто-то другой использует одно и то же имя глобального списка, все в порядке 2) вы можете иметь два экземпляры исполняемого кода шифрования/дешифратора, а также шифрование/дешифрование разных вещей, даже параллельно на разных потоках, без слияния глобалов друг друга.

Кроме того, этот код: ord(i.upper()) - ord('A') предоставит вам 0 для 'a' и 'A', 1 для 'b' и 'B', 2 для 'c' и 'C' ... и так далее, поэтому вам не нужны такие огромные цепи if/elif. (Почему это работает, потому что «A», «B», «C» и т. Д. Являются смежными в ASCII, поэтому «B» - «A» равно 1 и т. Д.)

3

Прежде всего, есть довольно сильные и практически нерушимая шифрования алгоритмов, некоторые из которых приходят расфасованных с питоном, таких как HMAC

import hmac 

def Hash_string(ref): 
     cypher = hmac.new('you secret word', 'plain-text') 
     return cypher.hexdigest() 

достаточно прост в использовании и гораздо сильнее. Вы также можете использовать blowfish для гораздо более продвинутых и безопасных проектов, хотя по умолчанию он не поставляется с python, но его достаточно просто настроить.

Теперь ваш код, вот как использовать глобальные переменные в питона

# declare variables as global 
global num1 
global num2 
num2=22 # give initial value to num2 

def foo(): 
    # bind variable names to the ones in global scope 
    global num2 
    print num2 # output: 22 
    num2 = 88 
    print num2 # output: 88 
    global num1 
    num1 = num2 

def bar(): 
    print num1 # output: 88 
    print num2 # output 88 

foo() 
bar() 

Таким образом, вы должны связать newtext с одной заявленной в качестве Gobal

Я также полагаю, что вы переписать шифровать, чтобы посмотреть что-то например,

alpha = ['a', 'b', 'c', 'd', 'e', ​​'f', 'g', 'h', 'i', 'j', ' к», 'L', 'т', 'N', 'о', 'р', 'Q', 'R', 's', 'т', 'и', 'V', 'W' , 'x', 'y', 'z']

число = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22, 23,24,25]

def map (ch): 
    chr = ch.lower() 
    return numeric[alpha.index(chr)] 

это создает отображение между числами и алфавитами, так что вы не будете нуждаться в длинный списке elifs

Надеется, что это помогает.

EDIT вы можете получить доступ к глобальным глобальным ключевым словам, но если вы хотите их изменить, сначала вам нужно привязать к глобальному var, прежде чем вы сможете их изменить.

РЕДАКТИРОВАТЬ изменить числовое значение [index (chr)], чтобы вернуть числовое значение [alpha.index (chr)] извините за ошибку :)

+0

NB: При моем первом редактировании я имею в виду, что вам не нужно для использования глобального ключевого слова при доступе к глобальным переменным, как показано на панели функций, однако, когда вам нужно их модифицировать, вам нужно использовать глобальное ключевое слово –

+0

, я знаю, что в питоне уже есть сильные и легкие шифровки. Я хотел сделать свое собственное шифрование. Спасибо за ответ! – astronautlevel