#Python #密码管理器 无需再记住密码,使用Python实现个人密码管理器
本文在CSDN"彭_Yu的博客"同步发表
目录
编辑
注:程序实例可到文末下载
1.要点
1.tkinter界面设计
2.SQLite数据库操作
3.字符串异或运算加密和解密
2.运行原理
1.用户需要记住一个统一的加解密密钥,对于各平台的密码,使用密钥字符串异或运算加密后存储到数据库,查询时使用同一个密钥进行密钥字符串异或解密。
2.需要注意的是,由于代码采用的是异或算法,所以密码字符串和密钥字符串不应有对应位置上相同的字符。
3.由于代码采用的是异或算法所以并不安全,他人猜到的加解密密钥与正确密钥越相似,解密出的密码也就与正确密码越相似。你可以改写加密和解密算法,实现更高级别的密码保护。
3.异或算法简介
XOR 是 exclusive OR 的缩写。英语的 exclusive 意思是"专有的,独有的",可以理解为 XOR 是更单纯的 OR 运算。
我们知道,OR 运算的运算子有两种情况,计算结果为
true。(1)一个为 true,另一个为 false;
(2)两个都为 true。
上面两种情况,有时候需要明确区分,所以引入了 XOR。
XOR 排除了第二种情况,只有第一种情况(一个运算子为
true,另一个为false)才会返回 true,所以可以看成是更单纯的 OR 运算。也就是说, XOR 主要用来判断两个值是否不同。XOR 一般使用插入符号(caret)
^表示。如果约定0为 false,1为 true,那么 XOR 的运算真值表如下。0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
4.运行效果
编辑
5.实现过程
5.1文件结构
/根目录
-MyPWD.exe(主程序)
-MyPWD.sqlite3(数据库文件)

5.2建立数据库
在这里我们可以使用在线sqlite查看器:
输入如下信息:
CREATE TABLE passwords (platform TEXT, pwd TEXT, id INTEGER PRIMARY KEY)

编辑
单击执行 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 数据库文件在同一目录下。
关于如何编译请查看我以前的一篇文章,做好准备操作但不要执行其中的编译命令,而是执行以下命令(执行前请保证目录结构与以下图片对应)。
做好准备操作后,执行如下代码:
cd X:\源代码
pyinstaller -F -w -i X:\源代码\icon.ico X:\源代码\MyPWD.py

编辑
出现如下字符说明编译成功,请将根目录中 dist 文件夹中的MyPWD.exe(主程序)放入 “MyPWD.sqlite3” 所在目录。
编辑
预祝使用顺利~
文章资源下载:
https://pan.baidu.com/s/1cW8kRcQFOF2tBBj05UZmZg
提取码:2xr7
感谢您的阅读,如觉得有用请您点赞,您的鼓励是对我的最大动力!
END
2022/12/24
联系我:pengyu717@yeah.net
#Python #密码管理器 无需再记住密码,使用Python实现个人密码管理器的更多相关文章
- 第一阶段——CentOS6_Python3.6.1笔记(尚学堂-Python基础快速入门)+ 【补充】麦子-Python程序入门与进阶
虚拟机环境: 设置网络 .修改网络地址 .设置网卡为nat模式 .确保物理机启动dhcp.net服务 .编辑文件:vim /etc/sysconfig/network-scripts/ifcfg-et ...
- web安全:防止浏览器记住或自动填写用户名和密码(表单)的终极解决方案
最近项目上要求做到这一点,在网上搜了一圈,发现都是不完美的,不兼容全部的浏览器,于是只能自己摸索了,最终得出了终极解决方案: 涉及: disabled 或 readonly display:none; ...
- Python笔记_第四篇_高阶编程_再议装饰器和再议内置函数
1. 概述: 我们在前面用了很多的装饰器这个工具的方法.这个位置要系统的讲一下装饰器. 1.2 为什么需要装饰器. 装饰器本质是一个Python函数,它可以让其他函数在不需要任何代码变动的前提下增加额 ...
- 如何找回Ucenter创始人密码,账号无需修改
UCenter 创始人的密码非常重要,忘记或丢失后,就不能进入 UCenter 进行用户和数据的管理,也会对站点造成安全隐患.由于 UCenter 的密码是采用两次 md5 加一个随机数的形式加密的, ...
- python之函数对象、函数嵌套、名称空间与作用域、装饰器
一 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多分支的if de ...
- python 全栈开发,Day12(函数的有用信息,带参数的装饰器,多个装饰器装饰一个函数)
函数的执行时,*打散.函数的定义时,*聚合. from functools import wraps def wrapper(f): # f = func1 @wraps(f) def inner(* ...
- 已禁用对分布式事务管理器(MSDTC)的网络访问。请使用组件服务管理工具启用 DTC 以便在 MSDTC 安全配置中进行网络访问。
今天写ASP.NET程序,在网页后台的c#代码里写了个事务,事务内部对一张表进行批量插入,对另外一张表进行查询与批量插入. 结果第二张表查询后foreach迭代操作时报错:已禁用对分布式事务管理器(M ...
- 忘记常访问网站密码怎么办?教你如何查看浏览器已保存的密码,如何简单查看Chome浏览器保存的密码?
利用场景: 同事或朋友外出有事,电脑未锁屏离开座位.可以利用这一间隙,查看Ta在Chrome浏览器上保存的账号密码 查看逻辑: 当我们要查看Chrome浏览器上保存的密码时,点击显示,会弹出一个对话框 ...
- MySQL忘记了密码登录不进去,用命令符修改新的密码重新登录的方法
MySQL忘记了密码登录不进去,用命令符修改新的密码重新登录的方法: 1.备份my.ini 2.在my.ini字段里 [mysqld] #socket=mysql skip-grant-tables ...
- 第十九章——使用资源调控器管理资源(1)——使用SQLServer Management Studio 配置资源调控器
原文:第十九章--使用资源调控器管理资源(1)--使用SQLServer Management Studio 配置资源调控器 本系列包含: 1. 使用SQLServer Management Stud ...
随机推荐
- ORA-01653:unable to extend table xxxxx by 8192 in tablespace xxxxx
原因:表空间满 解决:扩展表空间 报错截图: 参考摘录:https://blog.csdn.net/qq_35257875/article/details/90295272
- shell 每秒调用某个地址的方法
#!/bin/bash step=1 for (( i = 0; i < 60; i=(i+step) )); do curl http://fn.k6akg6f.bar/chat.php sl ...
- vue2的响应式原理
响应式的话,主要指的是这个状态改变以后,视图要去主动更新 这个过程,vue是通过两个步骤来实现的 1 数据的劫持 数据劫持也叫做数据拦截,通过Object.defineProperty来把对象中的每一 ...
- @JsonFormat
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8" 不管是前端传后台,还是后台传前端, ...
- Dockerfile CMD命令提示no such file
过程: 自制一个kafka镜像,启动时CMD命令报ERROR # 安装 kafka ADD kafka_2.12-2.4.1.tgz /home/pmish/software ENV KAFKA_HO ...
- 央行DR007在哪里查看
1.中国外汇交易中心,点击官网进入 https://www.chinamoney.com.cn/chinese/ 2.点击数据选项,接着选择货币市场行情 3.点击质押式回购
- k8s_使用k8s部署博客系统svc、secret、configmap(三)
service service是抽象Pod对外提供服务的地址,将其固化的作用:屏蔽因pod的创删以及扩缩容带来ip变化.service通过自身定义文件的selector的标签配置匹配到需要提供服务的对 ...
- 家里静态Ip设置
分配的网段是10.10.1.*
- CF1548B Integers Have Friends
洛咕 题意: 给定 \(n\) 和一个长度为 \(n\) 的数组 \(a\),求一个最长的区间 \(\left[l,r\right]\),使得存在 \(m\geq 2\) 和 \(k\),对于所有 \ ...
- [*]Quadratic Residual Networks: A New Class of Neural Networks for Solving Forward and Inverse Problems in Physics Involving PDEs
Accepted by SIAM International Conference on Data Mining (SDM21) 本文提出了二次残差网络,通过在应用激活函数之前,添加二次残差项到输入的 ...