【问题标题】:Checking if a string is in a file检查字符串是否在文件中
【发布时间】:2019-02-27 11:38:33
【问题描述】:

我正在制作一个程序来检查文件中是否有任何用户的输入。如果用户输入当前不在文件中,那么我们会将该输入附加到 used_pa​​sswords 文件中,并要求用户再次输入其他内容。否则,如果他们重新输入我们刚刚添加的输入(或任何预设),那么我们想告诉他们他们不能重复使用密码。

这段代码遇到的问题是,每当我键入来自 used_pa​​sswords 文件中单词的字母,或者如果我在文件中键入单词的一部分时,程序就会告诉我不能重用密码。

例如:如果我输入“abc”,程序会告诉我我已经重用了该密码,我假设这可能是因为程序逐字符读取文件并读取 abcdeF 中的 abc!23 .

虽然,我不希望程序告诉我我不能重用文件中的一个或多个字符。我希望程序告诉我我不能重复使用程序中的一个词


我也想知道我们是否可以将输入或预设放入文件中的数组中。

fileUsed_Pass = open("used_passwords.txt", 'a')

fileUsed_Pass.write("\nabcdeF!23")
fileUsed_Pass.write("\n\n")

fileUsed_Pass.write("zxcbhK#44")
fileUsed_Pass.write("\n\n")

fileUsed_Pass.write("poiuyT&11")
fileUsed_Pass.write("\n\n")

fileUsed_Pass.close()



def password():

    string = input("Enter Here:")

    if string in open('used_passwords.txt').read():
        print("You can not reuse that password!\n")
        password()
    else:
        # file-append.py
        f = open('used_passwords.txt','a')
        f.write('\n'+string)
        f.close()
        password()
password()

更新:我已经让代码使用 with 语句工作。

我没有使用 If 和 else 语句,而是使用了 with 语句。

我正在做的是检查每一行,看看它是否有任何与我的输入字符串匹配的文本。如果没有,那么我们将使 some_variable 等于 True。如果不是,那么我们将使其等于 false。

with open("used_passwords.txt", 'r') as tFile:
    for line in tFile:
      if string != line and string+"\n" != line:
        some_variable = True
      else:  #If it equals anything else from the file, then false
        some_variable = False
        break


  #print(some_variable)
  #this was added for me/the user to make sure that the with statement was working

之后,如果它等于 True:我们会将其添加到文件中。如果不是,我们会让用户输入另一个与文件中的任何密码都不匹配的密码。

  tFile = open("used_passwords.txt", 'a')
  if some_variable == True:
    tFile.write("\n" + string)
    print("\nGOOD! Password does not match old ones!")

  elif some_variable == False:
    print("\nYou can not re-use a password!")
    password()

【问题讨论】:

    标签: python string python-3.x file match


    【解决方案1】:

    考虑到您在文件中输入的每个密码后都添加了一个\n,您可以尝试将\n 附加到string 变量,然后在此之后进行搜索。

    【讨论】:

      【解决方案2】:

      您正在使用 .read(),它将整个文件作为一个字符串读取。

      word = 'abc'
      
      for line in open('file.txt').readlines():
          if word in line:
              return True
      

      改用 .readlines() 并循环遍历每一行以检查字符串是否在任何文件行中。

      【讨论】:

      • 我认为这与他的解决方案没有什么不同——如果文件中的一行是abc123,则在abc 上搜索将返回 True,这是他不想要的。
      • 很抱歉回复晚了,但是是的,当我在 abc 上搜索时,它总是让我返回 true。我需要它返回 false 表明它与 abc123 作为一个整体不匹配。
      【解决方案3】:

      直接使用文本文件可能不是最好的解决方案; 您应该考虑改用某种形式的数据库(例如 sqlite3 library,IIRC 预装了 Python3)。

      另外,请记住,将密码存储为明文是一种安全“禁忌”。 至少,使用众多可用的cryptographic hash functions 之一,然后存储和比较哈希,而不是密码。

      这是一个使用 sqlite3 和SHA-256 的基本示例,这是一个常见的散列函数:

      #!/usr/bin/python3
      
      import sqlite3
      import hashlib
      
      db  = sqlite3.connect( "used_passwords.db" )
      cur = db.cursor()
      cur.execute( "CREATE TABLE IF NOT EXISTS passwords( pwd TEXT, UNIQUE( pwd ))" )
      
      def password():
         pwd = input( "password: " )
         sha = hashlib.sha256( pwd.encode( 'utf-8' )).hexdigest()
         cur.execute( "INSERT INTO passwords VALUES( ? )", ( sha, ))
      
      while True:
         try:
            password()
            break
         except KeyboardInterrupt:
            print( "aborted" )
            break
         except sqlite3.IntegrityError:
            print( "cannot reuse that password" )
      
      db.commit()
      db.close()
      

      注意pwd 上的UNIQUE 约束,它确保只要passwords 中已经存在密码,就会引发sqlite3.IntegrityError 异常(这使得验证隐式,并最大限度地减少SQL 的繁琐性)。

      使用示例:

      % ./pwd.py 
      password: foo
      % ./pwd.py 
      password: foo
      cannot reuse that password
      password: bar
      %
      

      您可以验证数据库中没有出现明文密码:

      % sqlite3 ./used_passwords.db 
      SQLite version 3.16.2 2017-01-06 16:32:41
      Enter ".help" for usage hints.
      sqlite> select * from passwords;
      2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae  ; <- this is "foo"
      fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9  ; <- this is "bar"
      sqlite> 
      

      当然,您可以在此基础上进行扩展并添加更多功能,例如支持多用户、密码过期等...

      【讨论】:

      • 抱歉这么晚才回复!有事要做..除此之外,这不是我想要的,但这确实适用于我目前正在做的数据库分配:) 这个答案已经回答了一个我什至还没有问过堆栈溢出的问题。感谢您提供有关为什么我应该使用数据库的信息。 (我正在使用文件进行作业,现在正在做数据库作业)我会记住你所说的以备将来使用。
      • 虽然我还有一个问题,但是 KeyboardInterrupt 的作用是什么?
      • 很高兴看到这个答案最终对您有用。 KeyboardInterrupt 位使 Python 有机会在您使用 Ctrl+C 停止程序时干净地提交/关闭数据库(在这种情况下,通过中断主循环)。
      猜你喜欢
      • 1970-01-01
      • 2014-12-11
      • 2013-12-15
      • 1970-01-01
      • 2011-09-30
      • 2012-01-14
      • 2021-10-07
      • 2012-02-19
      • 1970-01-01
      相关资源
      最近更新 更多