Как построить эту программу без использования глобальных переменных? - PullRequest
1 голос
/ 19 апреля 2020

Я только что создал свой первый Python проект. Я уверен, что можно сделать много улучшений, но у меня есть один конкретный c вопрос о том, как изменить мой код.

Я читал, что неразумно использовать глобальные переменные (из-за по соображениям безопасности). Но я не уверен, как заставить несколько функций работать вместе (т.е. использовать одни и те же переменные), если они не являются глобальными.

Программа ниже выполняет три вещи:

  1. Генерация пароля .
  2. Зашифруйте этот пароль.
  3. Расшифруйте пароль.

Однако в части 2 я только объявил глобальные переменные для шифрования пароля.

Мой вопрос: как изменить код, чтобы избежать использования глобалов? Я вставил весь код ниже для справки, но глобальные объявлены в def listToString() и def passEncryptor():.

import random

#variables to hold a list and a string
Password = []
Encrypted = ''

#variables to hold the specific characters
#to use in creating the password
a = 'abcdefghijklmnopqrstuvwxyz'
b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
c = '0123456789'
d = '!@#$%^&*()'

#variable holds all possible values
#that could be found in the password
e = a + b + c + d

#variables will randomize the password length
sm = random.randint(2,3)
lg = random.randint(3,4)

#function generates a randomized password
def passwordGenerator() :

    #append elements from variables a - d
    #to the Password variable
    for x in range(sm) :
        Password.append(random.choice(a))
    for x in range(sm) :
        Password.append(random.choice(b))
    for x in range(lg) :
        Password.append(random.choice(c))
    for x in range(sm) :
        Password.append(random.choice(d))

    #randomize the order of the elements    
    random.shuffle(Password)

    #ensure the first element is a letter
    Password.insert(0, random.choice(a))

    #print to show that the program worked
    print(Password)

#call function to generate a randomized password
passwordGenerator()

#function to store 5 random elements in a string
def listToString() :

    #can't seem to get this to work
    #without using a global variable
    global rand5
    rand5 = ''
    x = random.choices(e, k=5)
    for val in x :
        rand5 += val
    return rand5

#for each element in the password
#add the random 5 elements from listToString()
def passEncryptor():

    global tempPass
    tempPass = ''
    for val in Password :

        #gets 5 new random elements
        listToString()

        #concatenate the random elements
        #with the real password
        tempPass += val + rand5

    print(tempPass)
passEncryptor()

#function to unencrypt an encrypted password
def passDecryptor():

    #convert the encrypted string to a list
    encryptedList = []
    for val in tempPass :
        encryptedList.append(val)

    #remove the random 5 elements    
    decrypt = encryptedList[::6]
    decrypted = ''
    #convert back to a string
    for val in decrypt :
        decrypted += val

    print(decrypted)

passDecryptor()

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

В этом случае это просто сводится к недостатку знаний - вы не пользуетесь параметрами функций - я предполагаю, что вы не знаете, что это такое, потому что если бы вы это сделали, вы бы предпочли их глобальным Переменные.

Я не знаю, что именно «безопасность» - это то, чем вы жертвуете при использовании глобальных переменных. Конечно, я могу думать о гипотетических примерах, и я уверен, что кто-то может привести некоторые реальные примеры, в которых использование глобальных переменных было серьезной проблемой безопасности ... Я имею в виду, что использование глобальных переменных не делает вашу программу по своей сути небезопасен - просто очень легко использовать их неправильно (есть ли правильный путь?). Существуют более эффективные решения для решения проблем, которые, по вашему мнению, вы можете решить только с помощью глобальных переменных.

Код, который вы разместили, действительно демонстрирует суть глобальных переменных - если я, пользователь вашей программы, хочу создать несколько паролей, результат, который я получаю, является неожиданным:

['d', 'q', '3', 'O', 'g', '1', '$', 'J', '&', '7']
dsLT(mq4N^Yy3(L)%iOr&VM3gTfaZq1&ud9B$RJJ1aJe6Nju&O2*rE7Zz@Y!
dq3Og1$J&7
>>> passwordGenerator()
['n', '&', 'E', ')', '7', '0', '&', 'O', '2', '1', '$', '3', 'q', 'q', 'k', 'J', 'B', '1', 'd', 'g']
>>> passwordGenerator()
['j', '9', 'd', '1', 'k', 'O', 'B', 'q', 'Q', '2', 'g', 'o', 'e', '7', '1', 'n', 'q', '$', 'J', '&', '!', '0', 'A', '!', 'E', ')', '3', '7', '&', '2']
>>> passwordGenerator()
['u', 'o', '!', ')', '0', 'j', 'h', '1', '!', 'q', '7', 'g', '$', '9', 'n', 'k', 'q', '1', '&', 'd', 'J', '2', 'B', '8', '3', '2', '&', '7', 'L', '*', 'O', '5', 'Q', 'e', '&', 'S', '2', 'E', 'A', 'x']
>>> passwordGenerator()
['o', 'h', 'u', '1', 'S', 'q', '&', '7', '$', 'g', '7', '8', '2', '3', 'J', '&', 'k', 'A', '9', 'q', '2', '1', '6', 'B', '0', '*', '&', '!', 'e', 'x', 'j', 'B', 'L', 'a', 'o', '9', ')', '$', 'n', '9', 'U', 's', '!', 'Q', 'E', '2', 'd', '&', '5', 'O']

passwordGenerator изменяет состояние глобальной переменной Password, добавляя к ней элементы каждый раз, когда вызывается функция. Вообще говоря, функция неожиданно изменяет состояние переменной (которая находится вне области действия функции). Вот почему глобальные переменные могут быть источником проблем, будь то безопасность или иным образом.

Это не связано, но вы также делаете некоторые ненужные вещи, такие как тасование Password после добавления к нему случайных символов. Вот как это может выглядеть с параметрами функции:

def get_random_password(alphabet):
    from random import randint, choices

    password_length = randint(5, 16)
    password = choices(alphabet, k=password_length)

    return "".join(password)


def get_encrypted(alphabet, plaintext):
    from random import choices

    return "".join(char + "".join(choices(alphabet, k=5)) for char in plaintext)

def get_decrypted(encrypted_plaintext):
    return encrypted_plaintext[::6]

def main():
    import string

    alphabet = string.digits + string.ascii_letters + string.punctuation
    # alphabet = string.printable.rstrip()

    password = get_random_password(alphabet)
    encrypted = get_encrypted(alphabet, password)
    decrypted = get_decrypted(encrypted)

    print(f"The password is \"{password}\"")
    print(f"Encrypted: \"{encrypted}\"")
    print(f"Decrypted: \"{decrypted}\"")


if __name__ == "__main__":
    main()

Вывод:

The password is "O*L7~"
Encrypted: "OiL)V\*I={w&LX5"2-7WF/\+~5%_mP"
Decrypted: "O*L7~"
>>> 

Я также добавил точку входа main и воспользовался стандартной библиотекой a немного более. Это тангенциально, но на самом деле вы не «зашифровываете» строку, строго говоря, это больше похоже на запутывание, но неважно.

0 голосов
/ 19 апреля 2020

Создайте класс и поместите ваши функции в качестве методов класса и переменные в качестве члена этого класса.

...