
#Python #密码管理器 无需再记住密码,使用Python实现个人密码管理器
本文在CSDN"彭_Yu的博客"同步发表
目录
1.要点
2.运行原理
3.异或算法简介
4.运行效果
5.实现过程
5.1文件结构
5.2建立数据库
5.3 Python代码
注:程序实例可到文末下载
1.要点
1.tkinter界面设计
2.SQLite数据库操作
3.字符串异或运算加密和解密
2.运行原理
1.用户需要记住一个统一的加解密密钥,对于各平台的密码,使用密钥字符串异或运算加密后存储到数据库,查询时使用同一个密钥进行密钥字符串异或解密。
2.需要注意的是,由于代码采用的是异或算法,所以密码字符串和密钥字符串不应有对应位置上相同的字符。
3.由于代码采用的是异或算法所以并不安全,他人猜到的加解密密钥与正确密钥越相似,解密出的密码也就与正确密码越相似。你可以改写加密和解密算法,实现更高级别的密码保护。
3.异或算法简介
XOR 是 exclusive OR 的缩写。英语的 exclusive 意思是"专有的,独有的",可以理解为 XOR 是更单纯的 OR 运算。
我们知道,OR 运算的运算子有两种情况,计算结果为true
。
上面两种情况,有时候需要明确区分,所以引入了 XOR。
XOR 排除了第二种情况,只有第一种情况(一个运算子为true
,另一个为false
)才会返回 true,所以可以看成是更单纯的 OR 运算。也就是说, XOR 主要用来判断两个值是否不同。
XOR 一般使用插入符号(caret)^
表示。如果约定0
为 false,1
为 true,那么 XOR 的运算真值表如下。
4.运行效果
5.实现过程
5.1文件结构
5.2建立数据库
在这里我们可以使用在线sqlite查看器:
在线sqlite查看器
输入如下信息:
单击执行 sql>导出Sqlite数据库文件 并将文件重命名为 “MyPWD.sqlite3” 放入MyPWD.exe(主程序)所在目录。
5.3 Python代码
| import sqlite3 |
| import tkinter |
| from itertools import cycle |
| from tkinter.ttk import Combobox |
| from tkinter.messagebox import showinfo, showerror, askyesno |
| class DatabaseAccess: |
| @staticmethod |
| def doSql(sql): |
| with sqlite3.connect('MyPWD.sqlite3') as conn: |
| conn.execute(sql) |
| conn.commit() |
| |
| @staticmethod |
| def getData(sql): |
| with sqlite3.connect('MyPWD.sqlite3') as conn: |
| cur = conn.cursor() |
| cur.execute(sql) |
| return cur.fetchall() |
| root = tkinter.Tk() |
| root.geometry('350x250+400+300') |
| root.resizable(False, False) |
| root.title('(C)2022彭_Yu') |
| lbKey = tkinter.Label(root, text='密码数据库密钥:') |
| lbKey.place(x=10, y=10, width=100, height=20) |
| key = tkinter.StringVar(root, '') |
| entryKey = tkinter.Entry(root, textvariable=key, show='*') |
| entryKey.place(x=120, y=10, width=200, height=20) |
| lbPlatform = tkinter.Label(root, text='平台 名称:') |
| lbPlatform.place(x=10, y=40, width=100, height=20) |
| platformName = tkinter.StringVar(root, '') |
| entryPlatform = tkinter.Entry(root, textvariable=platformName) |
| entryPlatform.place(x=120, y=40, width=200, height=20) |
| lbPassword = tkinter.Label(root, text='设置 密码:') |
| lbPassword.place(x=10, y=70, width=100, height=20) |
| password = tkinter.StringVar(root, '') |
| entryPassword = tkinter.Entry(root, textvariable=password) |
| entryPassword.place(x=120, y=70, width=200, height=20) |
| def add_modify(): |
| if not (key.get() and platformName.get() and password.get()): |
| showerror('出错', |
| '请同时输入密码数据库密钥、平台名称、密码.\n注意:密钥不要随意更改.') |
| return |
| if key.get().isdigit(): |
| showerror('密钥安全性出错', '为了您的密钥安全,不能使用纯数字作为密钥') |
| return |
| if sum(map(lambda x,y: x==y, password.get(), key.get())) > 0: |
| showerror('密钥安全性出错', '密码不合适,为了您的密钥安全,密码和密钥不能有对应位置相同的字符') |
| return |
| pwd = ''.join(map(lambda x,y: chr(ord(x)^ord(y)), password.get(), cycle(key.get()))) |
| sql = 'SELECT * FROM passwords WHERE platform="'+platformName.get()+'"' |
| if len(DatabaseAccess.getData(sql)) == 1: |
| sql = 'UPDATE passwords SET pwd="'+pwd+'" WHERE platform="'+platformName.get()+'"' |
| DatabaseAccess.doSql(sql) |
| showinfo('恭喜请求执行成功', '修改密码成功') |
| else: |
| sql = 'INSERT INTO passwords(platform,pwd) VALUES("'+platformName.get()+'","'+pwd+'")' |
| DatabaseAccess.doSql(sql) |
| bindPlatformNames() |
| showinfo('恭喜请求执行成功', '增加密码成功') |
| btnAddModify = tkinter.Button(root, |
| text='增加或修改密码', |
| bg='cyan', |
| fg='black', |
| command=add_modify) |
| btnAddModify.place(x=20, y=100, width=300, height=20) |
| lbChoosePlatform = tkinter.Label(root, text='请选择平台:') |
| lbChoosePlatform.place(x=10, y=130, width=100, height=20) |
| def bindPlatformNames(): |
| sql = 'SELECT platform FROM passwords' |
| data = DatabaseAccess.getData(sql) |
| data = [item[0] for item in data] |
| comboPlatform['values'] = data |
| comboPlatform = Combobox(root) |
| bindPlatformNames() |
| comboPlatform.place(x=120, y=130, width=200, height=20) |
| |
| lbResult = tkinter.Label(root, text='查询 结果:') |
| lbResult.place(x=10, y=160, width=100, height=20) |
| result = tkinter.StringVar(root, '') |
| entryResult = tkinter.Entry(root, textvariable=result) |
| entryResult['state'] = 'disabled' |
| entryResult.place(x=120, y=160, width=200,height=20) |
| def getPassword(): |
| if not comboPlatform.get().strip(): |
| showerror('出错', '还没选择平台名称') |
| return |
| if not key.get(): |
| showerror('出错', '请输入密钥') |
| return |
| sql = 'SELECT pwd FROM passwords WHERE platform="'+comboPlatform.get()+'"' |
| pwd = DatabaseAccess.getData(sql)[0][0] |
| pwd = ''.join(map(lambda x,y: chr(ord(x)^ord(y)), pwd, cycle(key.get()))) |
| result.set(pwd) |
| btnGetResult = tkinter.Button(root, |
| text='查询密码', |
| bg='cyan', |
| fg='black', |
| command=getPassword) |
| btnGetResult.place(x=20, y=190, width=149, height=20) |
| def deletePassword(): |
| if not comboPlatform.get().strip(): |
| showerror('出错', '您还没选择平台名称') |
| return |
| if not askyesno('请确认您的请求', '确定要删除吗?删除后不可恢复!'): |
| return |
| sql = 'DELETE FROM passwords WHERE platform="'+comboPlatform.get()+'"' |
| DatabaseAccess.doSql(sql) |
| showinfo('恭喜操作成功完成', '密码删除成功') |
| bindPlatformNames() |
| btnDelete = tkinter.Button(root, text='删除密码', |
| bg='red', fg='yellow', |
| command=deletePassword) |
| btnDelete.place(x=179, y=190, width=140, height=20) |
| root.mainloop() |

然后将此程序编译为exe,当然不编译也可以但要保证 MyPWD.py 文件与 MyPWD.sqlite3 数据库文件在同一目录下。
关于如何编译请查看我以前的一篇文章,做好准备操作但不要执行其中的编译命令,而是执行以下命令(执行前请保证目录结构与以下图片对应)。
#Python #日常技巧 #功能 将Python文件编译或打包成可执行(EXE)文件_python编译成可执行文件_彭_Yu的博客-CSDN博客#Python #日常技巧 #功能 将Python文件编译或打包成可执行(EXE)文件。将Python文件编译为exe文件后,可以直接在Windows上运行,不需要再依赖Python环境,可以复制到其他电脑中直接使用,较为方便。
https://blog.csdn.net/2201_75480799/article/details/128058849
做好准备操作后,执行如下代码:
出现如下字符说明编译成功,请将根目录中 dist 文件夹中的MyPWD.exe(主程序)放入 “MyPWD.sqlite3” 所在目录。
预祝使用顺利~
文章资源下载:
https://pan.baidu.com/s/1cW8kRcQFOF2tBBj05UZmZg
提取码:2xr7
感谢您的阅读,如觉得有用请您点赞,您的鼓励是对我的最大动力!
END
2022/12/24
联系我:pengyu717@yeah.net
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南