You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用bcrypt校验密码时哈希值引号去除问题求助

解决bcrypt校验存储于TXT文件中带引号哈希密码的问题

核心问题

你存储在database.txt中的哈希密码是字符串化的字节对象(比如b'$2b$12$...')或者带引号的字符串(比如"$2b$12$..."),而bcrypt.checkpw()需要的是原始字节类型的哈希值,直接去掉引号或b前缀再编码会导致哈希格式错误,校验失败。

解决方案

步骤1:统一哈希值的解析逻辑

不管存储的是带b'前缀的字符串还是带双引号的字符串,都需要:

  • 去除所有包裹的引号(单/双引号)
  • 去除开头的b前缀(如果存在)
  • 将处理后的字符串转换为字节类型(用utf-8编码)

步骤2:修正代码中的错误点

  • 原代码中elif y != None or x == None逻辑错误,应改为elif y != None and x == None,避免逻辑冲突
  • 读取文件时用with语句自动关闭文件,更安全
  • 处理空文件的逻辑错误:readlines()返回空列表而非None,判断应改为if not contant:

修正后的完整代码

import bcrypt

def Log_in():
    # 打印分隔线
    print("-"*70)

    # 提示用户输入用户名/邮箱及密码
    msg0 = "请输入您的用户名或电子邮箱地址"
    msg1 = "请输入您的密码"
    user_input = input(f"{msg0:45}| ")
    user_password = input(f"{msg1:45}| ")  # 修正原拼写错误:user_pasword -> user_password
    print("-"*70)
        
    # 用with语句安全读取文件
    email_list = []
    username_list = []
    password_list = []    
    with open("database.txt", 'r') as db:
        contant = db.readlines()
        
        # 处理文件内容
        for line in contant:
            line = line.strip()  # 先去除行首尾的换行/空格
            if not line:
                continue  # 跳过空行
            parts = line.split("| ")
            if len(parts) != 4:
                continue  # 跳过格式错误的行
            a, b, c, d = parts
            email_list.append(a.strip())
            username_list.append(b.strip())
            password_list.append(d.strip())
       
    # 检查输入的用户名/邮箱是否存在
    if user_input in username_list or user_input in email_list:
        x = username_list.index(user_input) if user_input in username_list else None
        y = email_list.index(user_input) if user_input in email_list else None
        
        # 获取对应的哈希值索引
        target_idx = x if x is not None else y
        if target_idx is None:
            print("密码错误")
            Log_in()
            return
        
        # 处理哈希值:去除引号、b前缀,转换为字节
        hashed_str = password_list[target_idx]
        # 去除所有引号(单/双)
        hashed_str = hashed_str.replace("'", "").replace('"', '')
        # 去除开头的b前缀(如果存在)
        if hashed_str.startswith('b'):
            hashed_str = hashed_str[1:]
        # 转换为字节类型
        hashed_bytes = hashed_str.encode('utf-8')
        
        # 执行校验
        if bcrypt.checkpw(user_password.encode('utf-8'), hashed_bytes):
            print("欢迎登录")
        else:
            print("密码错误")
            Log_in()
    else:
        print("该用户名或电子邮箱不存在")
        Log_in()
            
# 主函数                
if __name__ == "__main__":
    Log_in()

关键处理说明

  1. 哈希值清理:通过replace去除所有单双引号,再判断并去除开头的b前缀,确保得到纯哈希字符串,再编码为字节。
  2. 逻辑简化:合并用户名和邮箱的索引判断,避免重复代码和逻辑错误。
  3. 文件读取优化:使用with语句自动管理文件资源,跳过空行和格式错误的行,提升鲁棒性。
  4. 拼写修正:修正了原代码中user_pasword的拼写错误,避免变量名问题。

内容的提问来源于stack exchange,提问作者Omar Attia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:01:07