本文在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
。(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
本文作者:彭_Yu
转载请先联系pengyu717@163.com并注明原文链接:https://www.cnblogs.com/pyublog/p/17105402.html否则为侵权行为!
来源:https://www.cnblogs.com/pyublog/p/17105402.html
本站部分图文来源于网络,如有侵权请联系删除。