Python - 文件读取所需的帮助

时间:2017-08-19 19:12:05

标签: python python-3.x

我正在尝试创建一个简单的登录系统。我正在做的是将登录数据存储在名为' accounts.txt的文本文件中

现在,当用户厌倦登录时,它首先检查用户提供的用户名是否在' accounts.txt'中。如果它存在,则它要求输入密码,然后在' accounts.txt'

中检查密码是否与密码匹配
fr = open('accounts.txt', 'r')
while True:
username = input('Enter your username: ')  # Ask for their username

    if username in fr.read():  # Check if username exists
        password = input('Enter password: ')  # Ask for password if username exists

        if username+password in fr.read():
            print('Welcome ' + username)
            break
        else:
            print('Wrong password')

注意,accounts.txt中的密码保存为usernamepassword格式,所以如果用户名为jack,密码为gate,则txt文件中的实际密码为jackgate,因此我使用用户名+密码检查密码是否为正确的。

出现的问题是如果用户输入正确的用户名,那么程序会正确地向前移动,但即使输入的密码是正确的,它仍会显示“密码错误”。当第二次用户输入用户名时,它甚至会显示错误用户名的错误。我试着玩了很长时间的代码,但无法提出解决方案。我想这与fr.read()有关。我可以使用那个' fr'对象只有一次?

3 个答案:

答案 0 :(得分:1)

您可以使用startswithendswith

fr = [i.strip('\n') for i in open('accounts.txt')]

while True:
   username = input()
   if any(i.startswith(username) for i in fr):
       password = input('Enter password: ')
       if any(username+password == i for i in fr):
            print("welcome")
            break
       else:
           print("wrong password")

答案 1 :(得分:1)

我愿意

if password in fr.read():

而不是

if username+password in fr.read():

这是因为要在fr.read循环中获取if密码,首先必须在fr.read循环中传递if用户名。但是,我发现的唯一问题是,如果他们输入了正确的用户名,但为该用户名输入了错误的密码,但是另一个用户名的密码正确,它仍会通过。

这就是为什么我认为你应该使用字典而不是文本文件。 例如,如果允许的用户名是username和username1,密码是username和username1,那么在另一个.py文件中,你可以说。

username_password={'username':'username','username1':'username1'}

创建一个包含用户名和密码的字典。

让我们说你把那个文件命名为stuff.py。然后在必须在同一目录中的第二个文件中,您可以执行

from stuff import * #imports all values from stuff.py
while True:
    username = input('Enter your username: ') #gets username
    if username_password.has_key(username):
        password = input('Enter password: ')
        if password== username_password[username]:
            print('Welcome '+username)
            break
        else:
            print('Wrong password')
            break
    else:
        print('Wrong username')

我仍然不知道为什么你有一个while循环,但如果你想要它,它很好。另外,我添加了一个else循环,以防用户名错误。

答案 2 :(得分:1)

让我在回答您的问题时提出一些改进建议。我会完整地阅读帐户文件,因此您有一个内存结构。如果您在accounts[USER] -> PASS格式的字典中执行此操作,则可以根据以下代码轻松检查任何帐户。

关于我的建议(他们并不完全只回答你的问题,但恕我直言,编写登录代码的主题应该小心对待):

  • 我强烈建议以纯文本格式存储密码,无论应用程序的重要性如何,请始终使用哈希值。
  • 不要只存储密码哈希,请始终使用salting。
  • 不要告诉尝试登录的人,如果用户名或密码错误,请始终只说“那不是正确的组合”,这样就更容易入侵。
  • 请在此处找到有关Python中哈希函数的信息:https://docs.python.org/3/library/hashlib.html#randomized-hashing
  • 本网站对盐析和保护密码有很好的介绍:https://crackstation.net/hashing-security.htm
  • 您是否有用户并将用户名视为不区分大小写。这是一种完全有效的方法,但每次我必须使用这样的网站时都会让我感到烦恼(就像电子邮件地址不区分大小写)
  • 由于我是密码安全的全职,也许其他Stackoverflow用户之一可以参与评论并扩展此主题。

无论如何,这是我关于如何检查登录的问题的答案。我创建了一个函数check_account(),它返回TrueFalse,具体取决于所提供的凭据是否正确。

import hashlib
import os
import binascii

def check_account(usr, pwd):
    # read the accounts file, a simple CSV where
    # username, salt value and password hash are
    # stored in three columns separated by a pipe char
    accounts = {}
    fr = open('/users/armin/temp/test.csv', 'r')
    for line in [x.strip().split("|") for x in fr.readlines()]:
        accounts[line[0].lower()] = (line[1], line[2])
    fr.close()

    # now go looking if we do have the user account
    # in the dictionary
    if usr in accounts:
        credentials = accounts[usr]
        # credentials is a list with salt at index 0
        # and pwd hash at index 1
        # generate the hash form the functions parameters
        # and compare with our account
        h = hashlib.blake2b(salt=binascii.unhexlify(credentials[0]))
        h.update(pwd.encode('utf-8'))
        if credentials[1] == h.hexdigest():
            return True
        else:
            return False
    else:
        return False


def main():
    while True:
        username = input('Enter your username: ')  # Ask for their username
        password = input('Enter password: ')  # Ask for password if username exists
        if check_account(username.lower(), password):
            print("Welcome, {0}".format(username))
        else:
            print('Username or password unknown')


if __name__ == '__main__':
    main()

要为用户帐户创建数据,请使用此代码。

def create():
    username = input('Enter your username: ').lower()  # Ask for their username
    password = input('Enter password: ')  # Ask for password if username exists
    salt = binascii.hexlify(os.urandom(hashlib.blake2b.SALT_SIZE))
    print("SALT value:", salt)
    h = hashlib.blake2b(salt=binascii.unhexlify(salt))
    h.update(password.encode('utf-8'))
    print("Pwd hash:", h.hexdigest())