I am trying to write a program that runs only with a password in a specific file. The code there is this:

users = open('users.txt', 'r', 1) userlist = users.readline() i = 0 user = [] while userlist: password = str(userlist) user.insert(i, password) userlist = users.readline() i = i+1 users.close() uid = int(input('Your id: \n')) upassword = str(input('Your password: \n')) print(user[uid]) if user[uid]== upassword: cmd = input('Hello! \n') else: cmd = input('Incorrect password.\n>') 

The password file looks like this:

 1234 5678 

In theory, if you enter 0 first and then 1234, then it should show “Hello!”, But it shows “Incorrect password”. At the same time, the same pair of 1-5678 is recognized correctly. What to do in this case?

    3 answers 3

    You read the file line by line, but there is a line break "\ n". You do not take this moment into account. To clear extra and non-printable characters from strings, use the strip () function, for example.

    In your code, one of the ways will be to change the string

     if user[uid] == upassword: 

    on

     if user[uid].strip() == upassword: 

    although it is not very beautiful. But then there is a question about the quality of the code presented.

      The code in question can be rewritten as:

       #!/usr/bin/env python3 from pathlib import Path passwords = Path('users.txt').read_text().splitlines() uid = int(input('Your id: \n')) upassword = input('Your password: \n').strip() msg = 'Hello!' if passwords[uid] == upassword else 'Incorrect password.' print(msg) 

      Although storing cleartext passwords on a disk is not good, even entering a cleartext password is not safe, and it is not very convenient for users to remember their uid .

      You can store only the password hash and username instead of asking for the number. For example, to compare a password stored in /etc/passwd using the crypt module :

       #!/usr/bin/env python import pwd import crypt import getpass from hmac import compare_digest as compare_hash def login(): username = input('Your user name: ').strip() cryptedpasswd = pwd.getpwnam(username)[1] if cryptedpasswd: if cryptedpasswd == 'x' or cryptedpasswd == '*': raise ValueError('no support for shadow passwords') cleartext = getpass.getpass() return compare_hash(crypt.crypt(cleartext, cryptedpasswd), cryptedpasswd) else: return True # no password 

      If the password for the desired user is stored in /etc/shadow then you can use spwd.getspnam()[1] to get the password hash and run the script from the user who can read this file (root, shadow group).

      To get a password hash:

       >>> import crypt >>> crypt.crypt('p4$$wOrd') '$6$NR7pbExWXdzpEti/$3rIzv5vmkvriZie0Hu9Y1n3uCtBdqICn32WCdtfSKzsHFJSBvrPVNhfCuRYX8PwE/gJ8ORW.PurdXlUy1BbGS0' 

      To save to your file:

       >>> hashed_passwd = crypt.crypt('p4$$wOrd') >>> username = 'john' >>> with open('users.txt', 'a') as file: ... file.write(f'{username}:{hashed_passwd}\n') 

      To read and verify the password:

       #!/usr/bin/env python3 import crypt import getpass from hmac import compare_digest as compare_hash from pathlib import Path def login(): username = input('Your user name: ').strip() cryptedpasswd = next((passwd for line in Path('users.txt').read_text().splitlines() for user, passwd in [line.partition(':')[::2]] if user == username), None) if cryptedpasswd is not None: cleartext = getpass.getpass() return compare_hash(crypt.crypt(cleartext, cryptedpasswd), cryptedpasswd) else: return False # user not found msg = 'Hello!' if login() else 'Wrong credentials.' print(msg) 

        The answer is already given. I will offer my version. Maybe the author will be interested.

         users = open('users.txt', 'r') def init(): index = 0 users_list = [] for add in users.readlines(): users_list.insert(index, add) index += 1 ID = int(input('Enter ID: ')) Password = str(input('Enter PASSWORD: ')) if users_list[ID].strip() == Password: return True return False init() 

        Or so:

         users = open('users.txt', 'r') def init(): users_list = [add.strip() for add in users.readlines()] ID = int(input('Enter ID: ')) Password = str(input('Enter PASSWORD: ')) if users_list[ID] == Password: return True return False 

        As the man wrote above. The question of quality.