#Python #密码管理器 无需再记住密码,使用Python实现个人密码管理器

[复制链接]
发表于 2023-2-9 15:13:44 | 显示全部楼层 |阅读模式
​本文在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. (1)一个为 true,另一个为 false;
  2. (2)两个都为 true。
复制代码
       上面两种情况,有时候需要明确区分,所以引入了 XOR。
       XOR 排除了第二种情况,只有第一种情况(一个运算子为true,另一个为false)才会返回 true,所以可以看成是更单纯的 OR 运算。也就是说, XOR 主要用来判断两个值是否不同。
       XOR 一般使用插入符号(caret)^表示。如果约定0 为 false,1 为 true,那么 XOR 的运算真值表如下。
  1. 0 ^ 0 = 0
  2. 0 ^ 1 = 1
  3. 1 ^ 0 = 1
  4. 1 ^ 1 = 0
复制代码
4.运行效果 

​运行效果编辑5.实现过程 

5.1文件结构
  1. /根目录
  2. -MyPWD.exe(主程序)
  3. -MyPWD.sqlite3(数据库文件)
复制代码
5.2建立数据库

       在这里我们可以使用在线sqlite查看器:
在线sqlite查看器
       输入如下信息:
  1. CREATE TABLE passwords (platform TEXT, pwd TEXT, id INTEGER PRIMARY KEY)
复制代码
 
​输入信息编辑         单击执行 sql>导出Sqlite数据库文件  并将文件重命名为 “MyPWD.sqlite3”  放入MyPWD.exe(主程序)所在目录。
​单击执行 sql>导出Sqlite数据库文件编辑将文件重命名为 “MyPWD.sqlite3”  放入MyPWD.exe(主程序)所在目录编辑5.3 Python代码 
  1. import sqlite3
  2. import tkinter
  3. from itertools import cycle
  4. from tkinter.ttk import Combobox
  5. from tkinter.messagebox import showinfo, showerror, askyesno
  6. class DatabaseAccess:
  7.     @staticmethod
  8.     def doSql(sql):
  9.         with sqlite3.connect('MyPWD.sqlite3') as conn:
  10.             conn.execute(sql)
  11.             conn.commit()
  12.             
  13.     @staticmethod
  14.     def getData(sql):
  15.         with sqlite3.connect('MyPWD.sqlite3') as conn:
  16.             cur = conn.cursor()
  17.             cur.execute(sql)
  18.             return cur.fetchall()
  19. root = tkinter.Tk()
  20. root.geometry('350x250+400+300')
  21. root.resizable(False, False)
  22. root.title('(C)2022彭_Yu')
  23. lbKey = tkinter.Label(root, text='密码数据库密钥:')
  24. lbKey.place(x=10, y=10, width=100, height=20)
  25. key = tkinter.StringVar(root, '')
  26. entryKey = tkinter.Entry(root, textvariable=key, show='*')
  27. entryKey.place(x=120, y=10, width=200, height=20)
  28. lbPlatform = tkinter.Label(root, text='平台  名称:')
  29. lbPlatform.place(x=10, y=40, width=100, height=20)
  30. platformName = tkinter.StringVar(root, '')
  31. entryPlatform = tkinter.Entry(root, textvariable=platformName)
  32. entryPlatform.place(x=120, y=40, width=200, height=20)
  33. lbPassword = tkinter.Label(root, text='设置  密码:')
  34. lbPassword.place(x=10, y=70, width=100, height=20)
  35. password = tkinter.StringVar(root, '')
  36. entryPassword = tkinter.Entry(root, textvariable=password)
  37. entryPassword.place(x=120, y=70, width=200, height=20)
  38. def add_modify():
  39.     if not (key.get() and platformName.get() and password.get()):
  40.         showerror('出错',
  41.                   '请同时输入密码数据库密钥、平台名称、密码.\n注意:密钥不要随意更改.')
  42.         return
  43.     if key.get().isdigit():
  44.         showerror('密钥安全性出错', '为了您的密钥安全,不能使用纯数字作为密钥')
  45.         return
  46.     if sum(map(lambda x,y: x==y, password.get(), key.get())) > 0:
  47.         showerror('密钥安全性出错', '密码不合适,为了您的密钥安全,密码和密钥不能有对应位置相同的字符')
  48.         return
  49.     pwd = ''.join(map(lambda x,y: chr(ord(x)^ord(y)), password.get(), cycle(key.get())))
  50.     sql = 'SELECT * FROM passwords WHERE platform="'+platformName.get()+'"'
  51.     if len(DatabaseAccess.getData(sql)) == 1:
  52.         sql = 'UPDATE passwords SET pwd="'+pwd+'" WHERE platform="'+platformName.get()+'"'
  53.         DatabaseAccess.doSql(sql)
  54.         showinfo('恭喜请求执行成功', '修改密码成功')
  55.     else:
  56.         sql = 'INSERT INTO passwords(platform,pwd) VALUES("'+platformName.get()+'","'+pwd+'")'
  57.         DatabaseAccess.doSql(sql)
  58.         bindPlatformNames()
  59.         showinfo('恭喜请求执行成功', '增加密码成功')
  60. btnAddModify = tkinter.Button(root,
  61.                               text='增加或修改密码',
  62.                               bg='cyan',
  63.                               fg='black',
  64.                               command=add_modify)
  65. btnAddModify.place(x=20, y=100, width=300, height=20)
  66. lbChoosePlatform = tkinter.Label(root, text='请选择平台:')
  67. lbChoosePlatform.place(x=10, y=130, width=100, height=20)
  68. def bindPlatformNames():
  69.     sql = 'SELECT platform FROM passwords'
  70.     data = DatabaseAccess.getData(sql)
  71.     data = [item[0] for item in data]
  72.     comboPlatform['values'] = data
  73. comboPlatform = Combobox(root)
  74. bindPlatformNames()
  75. comboPlatform.place(x=120, y=130, width=200, height=20)
  76. lbResult = tkinter.Label(root, text='查询  结果:')
  77. lbResult.place(x=10, y=160, width=100, height=20)
  78. result = tkinter.StringVar(root, '')
  79. entryResult = tkinter.Entry(root, textvariable=result)
  80. entryResult['state'] = 'disabled'
  81. entryResult.place(x=120, y=160, width=200,height=20)
  82. def getPassword():
  83.     if not comboPlatform.get().strip():
  84.         showerror('出错', '还没选择平台名称')
  85.         return
  86.     if not key.get():
  87.         showerror('出错', '请输入密钥')
  88.         return
  89.     sql = 'SELECT pwd FROM passwords WHERE platform="'+comboPlatform.get()+'"'
  90.     pwd = DatabaseAccess.getData(sql)[0][0]
  91.     pwd = ''.join(map(lambda x,y: chr(ord(x)^ord(y)), pwd, cycle(key.get())))
  92.     result.set(pwd)
  93. btnGetResult = tkinter.Button(root,
  94.                               text='查询密码',
  95.                               bg='cyan',
  96.                               fg='black',
  97.                               command=getPassword)
  98. btnGetResult.place(x=20, y=190, width=149, height=20)
  99. def deletePassword():
  100.     if not comboPlatform.get().strip():
  101.         showerror('出错', '您还没选择平台名称')
  102.         return
  103.     if not askyesno('请确认您的请求', '确定要删除吗?删除后不可恢复!'):
  104.         return
  105.     sql = 'DELETE FROM passwords WHERE platform="'+comboPlatform.get()+'"'
  106.     DatabaseAccess.doSql(sql)
  107.     showinfo('恭喜操作成功完成', '密码删除成功')
  108.     bindPlatformNames()
  109. btnDelete = tkinter.Button(root, text='删除密码',
  110.                            bg='red', fg='yellow',
  111.                            command=deletePassword)
  112. btnDelete.place(x=179, y=190, width=140, height=20)
  113. 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
         做好准备操作后,执行如下代码:
  1. cd X:\源代码
  2. 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


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表