用Python和Tkinter标准模块建立密码管理器

用Python和Tkinter标准模块建立密码管理器

创建一个简单的密码管理器应用程序,帮助用户存储和管理他们的密码。使用Python的tkinter模块来创建一个图形用户界面(GUI)。

本程序支持 添加、查看、搜索、复制、修改、删除 功能。

本程序使用 SQLite建立 passwords.db用以保存密码信息。

通过强制所有密码相关操作以字符串形式处理,解决前导零丢失问题。

Base64是Python的标准库模块之一,用于进行Base64编码和解码操作。Base64并不是一种加密算法,而是一种编码方案,它不适合用于保护敏感信息,在此用于简化演示。如果需要保护敏感信息(如密码),应使用真正的加密算法(如 AES)。

运行效果:

源码如下:

import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
import base64# 加密函数(强制输入为字符串)
def encrypt(password):password_str = str(password)  # 强制转为字符串return base64.b64encode(password_str.encode()).decode()# 解密函数(直接返回字符串)
def decrypt(encrypted_password):decrypted_bytes = base64.b64decode(encrypted_password.encode())return decrypted_bytes.decode()  # 直接返回字符串# 初始化数据库
def init_db():conn = sqlite3.connect("passwords.db")cursor = conn.cursor()cursor.execute("""CREATE TABLE IF NOT EXISTS passwords (id INTEGER PRIMARY KEY AUTOINCREMENT,project TEXT NOT NULL,username TEXT NOT NULL,password TEXT NOT NULL)""")conn.commit()conn.close()# 添加密码(强制密码为字符串)
def add_password():project = project_entry.get()username = username_entry.get()password = password_entry.get()if not project or not username or not password:messagebox.showwarning("输入错误", "请填写所有字段!")returnencrypted_password = encrypt(str(password))  # 强制转为字符串conn = sqlite3.connect("passwords.db")cursor = conn.cursor()cursor.execute("INSERT INTO passwords (project, username, password) VALUES (?, ?, ?)",(project, username, encrypted_password))conn.commit()conn.close()project_entry.delete(0, tk.END)username_entry.delete(0, tk.END)password_entry.delete(0, tk.END)view_passwords()# 查看密码(显示时强制转为字符串)
def view_passwords():for row in tree.get_children():tree.delete(row)conn = sqlite3.connect("passwords.db")cursor = conn.cursor()cursor.execute("SELECT id, project, username, password FROM passwords")rows = cursor.fetchall()conn.close()for row in rows:id, project, username, encrypted_password = rowdecrypted_password = decrypt(encrypted_password)tree.insert("", tk.END, values=(id, project, username, str(decrypted_password)))# 搜索密码
def search_password():search_term = search_entry.get()for row in tree.get_children():tree.delete(row)conn = sqlite3.connect("passwords.db")cursor = conn.cursor()cursor.execute("SELECT id, project, username, password FROM passwords WHERE project LIKE ?",(f"%{search_term}%",))rows = cursor.fetchall()conn.close()for row in rows:id, project, username, encrypted_password = rowdecrypted_password = decrypt(encrypted_password)tree.insert("", tk.END, values=(id, project, username, str(decrypted_password)))# 复制密码(关键修复:直接从数据库获取)
def copy_password():selected_item = tree.selection()if not selected_item:messagebox.showwarning("未选择", "请选择一条记录!")return# 获取选中行的项目名和用户名item = tree.item(selected_item)project = item["values"][1]username = item["values"][2]# 直接从数据库查询原始密码conn = sqlite3.connect("passwords.db")cursor = conn.cursor()cursor.execute("SELECT password FROM passwords WHERE project = ? AND username = ?", (project, username))row = cursor.fetchone()conn.close()if row:encrypted_password = row[0]decrypted_password = decrypt(encrypted_password)root.clipboard_clear()root.clipboard_append(str(decrypted_password))  # 强制转为字符串messagebox.showinfo("复制成功", "密码已复制到剪贴板!")else:messagebox.showerror("错误", "未找到密码!")# 删除记录
def delete_password():selected_item = tree.selection()if not selected_item:messagebox.showwarning("未选择", "请选择一条记录!")returnitem = tree.item(selected_item)record_id = item["values"][0]confirm = messagebox.askyesno("确认删除", "确定要删除这条记录吗?")if not confirm:returnconn = sqlite3.connect("passwords.db")cursor = conn.cursor()cursor.execute("DELETE FROM passwords WHERE id = ?", (record_id,))conn.commit()conn.close()view_passwords()# 修改记录(关键修复:输入框获取值强制为字符串)
def edit_password():selected_item = tree.selection()if not selected_item:messagebox.showwarning("未选择", "请选择一条记录!")returnitem = tree.item(selected_item)record_id = item["values"][0]# 直接从数据库获取原始密码conn = sqlite3.connect("passwords.db")cursor = conn.cursor()cursor.execute("SELECT project, username, password FROM passwords WHERE id = ?", (record_id,))project, username, encrypted_password = cursor.fetchone()conn.close()current_password = decrypt(encrypted_password)edit_window = tk.Toplevel(root)edit_window.title("修改记录")edit_window.geometry("300x200")# 项目名ttk.Label(edit_window, text="项目名:").grid(row=0, column=0, padx=5, pady=5)project_entry = ttk.Entry(edit_window, width=25)project_entry.grid(row=0, column=1, padx=5, pady=5)project_entry.insert(0, project)# 用户名ttk.Label(edit_window, text="用户名:").grid(row=1, column=0, padx=5, pady=5)username_entry = ttk.Entry(edit_window, width=25)username_entry.grid(row=1, column=1, padx=5, pady=5)username_entry.insert(0, username)# 密码(关键:输入框直接使用字符串,避免转换)ttk.Label(edit_window, text="密码:").grid(row=2, column=0, padx=5, pady=5)password_entry = ttk.Entry(edit_window, width=25)password_entry.grid(row=2, column=1, padx=5, pady=5)password_entry.insert(0, str(current_password))  # 强制转为字符串def save_edit():new_project = project_entry.get()new_username = username_entry.get()new_password = password_entry.get()  # 直接获取字符串if not new_project or not new_username or not new_password:messagebox.showwarning("输入错误", "请填写所有字段!")returnencrypted_password = encrypt(str(new_password))  # 加密前确保为字符串conn = sqlite3.connect("passwords.db")cursor = conn.cursor()cursor.execute("""UPDATE passwords SET project = ?, username = ?, password = ?WHERE id = ?""", (new_project, new_username, encrypted_password, record_id))conn.commit()conn.close()messagebox.showinfo("成功", "记录已更新!")edit_window.destroy()view_passwords()save_button = ttk.Button(edit_window, text="保存", command=save_edit)save_button.grid(row=3, column=0, columnspan=2, pady=10)# 初始化数据库
init_db()# 创建主窗口
root = tk.Tk()
root.title("密码管理器")
root.geometry("800x600")# 输入区域
input_frame = ttk.LabelFrame(root, text="添加密码")
input_frame.pack(fill=tk.X, padx=10, pady=10)ttk.Label(input_frame, text="项目名:").grid(row=0, column=0, padx=5, pady=5)
project_entry = ttk.Entry(input_frame, width=30)
project_entry.grid(row=0, column=1, padx=5, pady=5)ttk.Label(input_frame, text="用户名:").grid(row=1, column=0, padx=5, pady=5)
username_entry = ttk.Entry(input_frame, width=30)
username_entry.grid(row=1, column=1, padx=5, pady=5)ttk.Label(input_frame, text="密码:").grid(row=2, column=0, padx=5, pady=5)
password_entry = ttk.Entry(input_frame, width=30)
password_entry.grid(row=2, column=1, padx=5, pady=5)add_button = ttk.Button(input_frame, text="添加", command=add_password)
add_button.grid(row=3, column=0, columnspan=2, pady=10)# 搜索区域
search_frame = ttk.LabelFrame(root, text="搜索密码")
search_frame.pack(fill=tk.X, padx=10, pady=10)ttk.Label(search_frame, text="搜索项目名:").grid(row=0, column=0, padx=5, pady=5)
search_entry = ttk.Entry(search_frame, width=30)
search_entry.grid(row=0, column=1, padx=5, pady=5)search_button = ttk.Button(search_frame, text="搜索", command=search_password)
search_button.grid(row=0, column=2, padx=5, pady=5)show_all_button = ttk.Button(search_frame, text="全部显示", command=view_passwords)
show_all_button.grid(row=0, column=3, padx=5, pady=5)# 密码列表
tree_frame = ttk.LabelFrame(root, text="密码列表")
tree_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)columns = ("id", "project", "username", "password")
tree = ttk.Treeview(tree_frame, columns=columns, show="headings")
tree.heading("project", text="项目名")
tree.heading("username", text="用户名")
tree.heading("password", text="密码")
tree.column("id", width=0, stretch=tk.NO)  # 隐藏ID列
tree.column("password", width=150)
tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)# 操作按钮区域
button_frame = ttk.Frame(tree_frame)
button_frame.pack(pady=10)copy_button = ttk.Button(button_frame, text="复制密码", command=copy_password)
copy_button.pack(side=tk.LEFT, padx=5)edit_button = ttk.Button(button_frame, text="修改记录", command=edit_password)
edit_button.pack(side=tk.LEFT, padx=5)delete_button = ttk.Button(button_frame, text="删除记录", command=delete_password)
delete_button.pack(side=tk.LEFT, padx=5)# 首次加载显示数据
view_passwords()# 运行主循环
root.mainloop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/6728.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenAI模块重构

文章目录 1.common-openai-starter1.目录结构2.OpenAiProperties.java 新增apiUrl3.OpenAIAutoConfiguration.java4.OpenAiClient.java 使用gson重构 2.common-openai-starter-demo1.目录结构2.application.yml 新增api-url3.OpenAiController.java4.OpenAiApplication.java5.测…

数据标注开源框架 Label Studio

数据标注开源框架 Label Studio Label Studio 是一个开源的、灵活的数据标注平台,旨在帮助开发者和数据科学家轻松创建高质量的训练数据集。它支持多种类型的数据(如文本、图像、音频、视频等)以及复杂的标注任务(如分类、命名实体…

详解:TCP/IP五层(四层)协议模型

一.五层(四层)模型 1.概念 TCP/IP协议模型分为五层:物理层、数据链路层、网络层、传输层和应用层。这五层每一层都依赖于其下一层给它提供的网络去实现需求。 1)物理层:这是最基本的一层,也是最接近硬件…

使用Python进行大模型的测试与部署

随着人工智能技术的飞速发展,大规模模型在各行各业的应用日益广泛。然而,如何有效测试这些模型以确保其稳定性和准确性,成为测试人员的们面临的一大挑战。本文将详细介绍在Python环境下,如何测试大模型,并探讨其部署策…

高并发处理 --- 超卖问题+一人一单解决方案

在高并发场景下,超卖和一人一单是两个典型的并发问题。为了解决这两个问题,我们可以使用乐观锁(CAS)和悲观锁,这两者分别有不同的实现方式和适用场景。下面我们详细介绍如何通过 乐观锁(CAS) 和…

【2024年华为OD机试】(C卷,100分)- 约瑟夫问题 (JavaScriptJava PythonC/C++)

一、问题描述 题目描述 输入一个由随机数组成的数列(数列中每个数均是大于 0 的整数,长度已知),和初始计数值 m。 从数列首位置开始计数,计数到 m 后,将数列该位置数值替换计数值 m,并将数列…

浅谈APP之历史股票通过echarts绘图

浅谈APP之历史股票通过echarts绘图 需求描述 今天我们需要做一个简单的历史股票收盘价格通过echarts进行绘图,效果如下: 业务实现 代码框架 代码框架如下: . 依赖包下载 我们通过网站下载自己需要的涉及的图标,勾选之后进…

【0x0012】HCI_Delete_Stored_Link_Key命令详解

目录 一、命令参数 二、命令格式及参数 2.1. HCI_Delete_Stored_Link_Key 命令格式 2.2. BD_ADDR 2.3. Delete_All 三、生成事件及参数 3.1. HCI_Command_Complete事件 3.2. Status 3.3. Num_Keys_Deleted 四、命令执行流程 4.1. 命令发送阶段 4.2. 控制器处理阶段…

提示词的艺术 ---- AI Prompt 进阶(提示词框架)

提示词的艺术 ---- AI Prompt 进阶(提示词框架) 写在前面 上周发布了一篇《提示词的艺术----AI Prompt撰写指南》,旨在帮助读者理解提示词的作用,以及简单的提示词撰写指南。本篇作为进阶内容,将给出常用的提示词框架…

javaSE.类的继承

在定义不同类的时候,为了方便使用可以将这些共同属性抽象成一个父类,在定义其他子类时可以继承自该父类,减少代码的重复定义,子类可以使用父类中非私有成员. extents 没有可用的无形参构造方法 被构造方法覆盖了 super 需要调用父类的构造方法 super必须是构造主体的第一条语…

统计文本文件中单词频率的 Swift 与 Bash 实现详解

网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…

qt QUrl详解

1、概述 QUrl是Qt框架中用于处理URL(统一资源定位符)的类,它提供了构建、解析、编码、解码和处理URL的功能。QUrl支持多种协议,如HTTP、HTTPS、FTP以及文件URL等,并能处理URL的各个组成部分,如协议、主机、…

c++----------------------多态

1.多态 1.1多态的概念 多态(polymorphism)的概念:通俗来说,就是多种形态。多态分为编译时多态(静态多态)和运⾏时多 态(动态多态),这⾥我们重点讲运⾏时多态,编译时多态(静态多态)和运⾏时多态(动态多态)。编译时 多态(静态多态)…

javaSE.类与对象

类与对象 人类,鸟类,鱼类... 例如人,具有不同性格,但根本上都是人。 对象是某一类事物实际存在的每个个体(实例)例如:雷军 A:谁拿走了我的手机? B:是个人(类&#xff0…

Windows cmd常用命令

文章目录 Windows cmd常用命令一、引言二、文件和目录操作1、查看和切换目录2、文件和目录的创建与删除 三、系统信息与网络配置1、系统信息2、网络配置 四、使用示例五、总结 Windows cmd常用命令 一、引言 Windows 命令提示符(cmd)是一个强大的工具&a…

保健食品注册数据库<一键查询保健食品信息>

在保健品市场竞争激烈的情况下,企业要如何保障产品合规、信息公开,并且能够迅速应对市场变化呢?查询保健食品注册信息是关键环节。 当下,查询保健食品注册信息主要有两种途径:一是利用国家保健食品注册数据库进行查询…

无所不搜,吾爱制造

吾爱论坛作为众多软件资源爱好者的宝藏之地,汇聚了许多优秀的软件作品,堪称软件界的“福地”。许多技术大佬在这里分享自己的创作。 而今天要介绍的,正是吾爱作者“buyaobushuo”自制的多功能娱乐软件——太极。这款软件基于flet开发&#x…

【C++】详细讲解继承(下)

本篇来继续说说继承。上篇可移步至【C】详细讲解继承(上) 1.继承与友元 友元关系不能继承 ,也就是说基类友元不能访问派⽣类私有和保护成员。 class Student;//前置声明class Same //基类 { public:friend void Fun(const Same& p, con…

【二叉树】4. 判断一颗二叉树是否是平衡二叉树。5. 对称二叉树。6. 二叉树的构建及遍历 7. 二叉树的分层遍历 。

判断一颗二叉树是否是平衡二叉树。OJ链接 可以在求树高度的过程中判断树是否平衡 对称二叉树。OJ链接 二叉树的构建及遍历。OJ链接 注意:public static int i最好把static去掉 否则当有多个测试用例时 i无法重新为0二叉树的分层遍历 。OJ链接 但此题要求返回List…

代码随想录刷题day14(2)|(链表篇)02.07. 链表相交(疑点)

目录 一、链表理论基础 二、链表相交求解思路 三、相关算法题目 四、疑点 一、链表理论基础 代码随想录 二、链表相交求解思路 链表相交时,是结点的位置,也就是指针相同,不是结点的数值相同; 思路:定义两个指针…