python实现一个加密的文字处理器

这是一个类似于记事本的文字处理器。与正常的记事本不同的是,它会将文本文档进行加密,确保无法被常规的程序打开。

由于本人是一位业余编程爱好者,对于“python之禅”之类的规则比较不以为然,因此本程序代码也许有些许凌乱(当然不利于后期修改)。

这篇文章我早已发布过,但当时只给出了代码,并加了一些注释。现在,我希望在这里详细解释这个程序。

首先,对于一个适合我们广大中华儿女使用的程序,我们不可避免地要使用中文。这就需要对编码进行声明:

  #  coding:utf-8  

然后,就到了模块导入的环节了。我们这里需要tkinter,windnd,os和sys。windnd可以用pip安装,tkinter则需要在安装python时勾选:

  from  tkinter  import  *
from tkinter.filedialog import *
from tkinter.messagebox import *
import windnd import os import sys

接下来,我们会看到这样一段代码:

  try  :
filename
= sys.argv[1 ] except :
filename
= ""

这是干什么的呢?我们知道,对于exe程序,有一个“Open with”功能,也就是可以将拖动到exe文件或其快捷方式的文件打开。事实上,py文件也有这个功能,但是多数情况下这样操作后只能使程序正常运行,而不能对文件进行任何操作。而“sys.argv[1]”的作用就是,读取这个文件的路径信息。这样,我们就可以用open或sys库里的一些指令进行对文件的操作了。

  def  encryption(c, d):
c
= list(c + d)
g
= list(d)
d
= 0 for i in g:
d
*= ord(i)
d
=round(abs(d)**0.5 )
f
= " 0x "
for i in c:
e
=str(ord(i)+ d)
d
=round(300*(d**0.5 ))
f
=f+e+ " a " f =eval(f[:-1 ]) return (f)
def decrypt(c,d):
c
= hex(int(c)) print (c)
c
=c[2:].split( " a " )
z
= d
g
= list(d)
d
= 0 for i in g:
d
*= ord(i)
d
= round(abs(d) ** 0.5 )
f
= ""
for i in c:
e
= chr(int(i)- d)
d
= round(300 * (d ** 0.5 ))
f
= f + e if f[-len(z):]== z:
f
=f[:- len(z)] return (f) else :
c
= " bbc " +12

这一段就比较劲爆了。它定义了两个函数,一个用于加密,另外一个用于解密(顺便说一句,我英语不太好,有的函数或变量的名字可能比较古怪,请见谅)。

encryption是加密的函数(呃,这个应该叫做encrypt,我编这个程序时大脑有些短路,但既然已经这样了,也就不改了),它会将明文(输入的c)通过与密钥d有关的某些运算,得出一个十六进制数,然后将其转化为十进制。同时,为了确保解密结果唯一,将密钥一起连接在明文上,起校验作用。在这里,对于明文的每一个字符都会将加密过程中实际使用的密钥进行变动,因此基本是不可能通过字符出现频率的规律来破解的。由于密钥是字符,暴力拆解也基本不可能。

decrypt是解密,它大致就是encryption的逆操作,同时如果校验的结果有误,或是遇到其他解密失败的情况它会产生错误(因此使用时需要try-except,来确保程序不会退出,同时对解密失败的情况进行处理)。

接下来是基本的文件操作部分:

  def  mynew(aaa=1 ):  global  top, filename, textPad
top.title(
" 无标题 - 加密文本编辑器 " )
filename
= None
textPad.delete(
1.0 , END)
textPad.insert(
1.0, "" )
def myopen(aaa=1 ): global filename,kkk
filename
= askopenfilename() if filename == "" :
filename
= None else :
top.title(os.path.basename(filename)
+ " - 加密文本编辑器 " )
format
=os.path.basename(filename)[os.path.basename(filename).find( " . " )+1 :]
textPad.delete(
1.0 , END) try :
f
= open(filename, ' rb ' )
c
= f.read()
ccc
= str(c)[2:-1 ]
ccc.replace(
" \\ " , "" )
textPad.insert(
1.0 ,decrypt(ccc,format))
kkk
=1
except :
f.close()
try :
f
= open(filename, ' r ' , encoding= " gbk " ) try :
c
= f.read() except :
f.close()
f
= open(filename, ' r ' , encoding= " utf-8 " )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0 except :
f.close()
f
= open(filename, ' rb ' )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0
f.close()
def mysave(aaa=1 ): global filename,kkk try :
msg
= textPad.get(1.0, ' end ' )[0:-1 ] if kkk== 0:
f
= open(filename, ' w ' , encoding= " utf-8 " )
f.write(msg)
else :
f
= open(filename, ' wb ' )
fffff
= str(encryption(msg, format))
fffff
= eval( " b'{}' " .format(fffff)) print (fffff)
f.write(fffff)
f.close()
except :
mysaveas()
def mysaveas(aaa=1 ): global filename
f
= asksaveasfilename(initialfile= " 无标题.txt " )
filename
= f
format
= os.path.basename(filename)[os.path.basename(filename).find( " . " ) + 1 :]
msg
= textPad.get(1.0, ' end ' )[0:-1 ] if not format == " py " and not format== " bat " and not format == " pyw " and not format == " cmd " :
fh
= open(filename, ' wb ' )
fffff
= str(encryption(msg, format))
fffff
= eval( " b'{}' " .format(fffff)) print (fffff)
fh.write(fffff)
else :
fh
= open(filename, ' w ' , encoding= " utf-8 " )
fh.write(msg)
fh.close()
top.title(os.path.basename(f)
+ " - 加密文本编辑器 " )
def opened(files): global filename,kkk
ff
= ' \n ' .join((item.decode( ' gbk ' ) for item in files))
filename
= ff if filename == "" :
filename
= None else :
top.title(os.path.basename(filename)
+ " - 加密文本编辑器 " )
format
= os.path.basename(filename)[os.path.basename(filename).find( " . " ) + 1 :]
textPad.delete(
1.0 , END) try :
f
= open(filename, ' rb ' )
c
= f.read()
ccc
= str(c)[2:-1 ]
ccc.replace(
" \\ " , "" )
textPad.insert(
1.0 , decrypt(ccc, format))
kkk
= 1
except :
f.close()
try :
f
= open(filename, ' r ' , encoding= " gbk " ) try :
c
= f.read() except :
f.close()
f
= open(filename, ' r ' , encoding= " utf-8 " )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0 except :
f.close()
f
= open(filename, ' rb ' )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0
f.close()
  def  mynew(aaa=1 ):  global  top, filename, textPad
top.title(
" 无标题 - 加密文本编辑器 " )
filename
= None
textPad.delete(
1.0 , END)
textPad.insert(
1.0, "" )

首先说mynew(新建)。这里有一个可选参数a,这是因为通过bind激活函数会输入一个参数(这点我非常反感),为了不让程序运行出错,就添加了一个可选参数。这个其实没啥好说。global后面是所需的全局变量,然后就是设置窗口名称、文件名称,并清空输入框,很简单,很明了。

  def  myopen(aaa=1 ):  global  filename,kkk
filename
= askopenfilename() if filename == "" :
filename
= None else :
top.title(os.path.basename(filename)
+ " - 加密文本编辑器 " )
format
=os.path.basename(filename)[os.path.basename(filename).find( " . " )+1 :]
textPad.delete(
1.0 , END) try :
f
= open(filename, ' rb ' )
c
= f.read()
ccc
= str(c)[2:-1 ]
ccc.replace(
" \\ " , "" )
textPad.insert(
1.0 ,decrypt(ccc,format))
kkk
=1
except :
f.close()
try :
f
= open(filename, ' r ' , encoding= " gbk " ) try :
c
= f.read() except :
f.close()
f
= open(filename, ' r ' , encoding= " utf-8 " )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0 except :
f.close()
f
= open(filename, ' rb ' )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0
f.close()

然后就是myopen(打开)。“filename=askopenfilename()”就是,弹出一个选择打开的文件的窗口,并将结果存入filename。然后我们获取文件的后缀信息,作为解密所需的密钥。接下来,我们先尝试解密文件。如果执行中有错误,也就是无法解密,则用gbk编码正常打开,仍然打开失败,则使用utf-8。当然,如果都失败了,就用rb模式,也就是字节流的形式打开。

  def  mysave(aaa=1 ):  global  filename,kkk  try  :
msg
= textPad.get(1.0, ' end ' )[0:-1 ] if kkk== 0:
f
= open(filename, ' w ' , encoding= " utf-8 " )
f.write(msg)
else :
f
= open(filename, ' wb ' )
fffff
= str(encryption(msg, format))
fffff
= eval( " b'{}' " .format(fffff)) print (fffff)
f.write(fffff)
f.close()
except :
mysaveas()

接下来,我们讲mysave(保存)。将输入框中的内容存入变量msg,然后写入文件,当然,如果filename是None,会产生错误,然后执行mysaveas,也就是另存。这里有一个判定,判定kkk的值是否是1。kkk的值是1,意味着当前打开的文件是曾被加密的文件,因为打开这样的文件时会自动将kkk设置为1;反之,则只可能是打开的其他未加密文件,如果是这样,编辑后依然不加密,以免损坏文件。这里要注意,当当前文件为新建文件时,不会执行保存的写入程序,而是会在另存里执行,因此对于这一类文件的加密与否,不会与kkk挂钩。

  def  mysaveas(aaa=1 ):  global  filename
f
= asksaveasfilename(initialfile= " 无标题.txt " )
filename
= f
format
= os.path.basename(filename)[os.path.basename(filename).find( " . " ) + 1 :]
msg
= textPad.get(1.0, ' end ' )[0:-1 ] if not format == " py " and not format== " bat " and not format == " pyw " and not format == " cmd " :
fh
= open(filename, ' wb ' )
fffff
= str(encryption(msg, format))
fffff
= eval( " b'{}' " .format(fffff)) print (fffff)
fh.write(fffff)
else :
fh
= open(filename, ' w ' , encoding= " utf-8 " )
fh.write(msg)
fh.close()
top.title(os.path.basename(f)
+ " - 加密文本编辑器 " )

Next,就是mysaveas(另存)。首先,和打开一样,它会弹出一个窗口,这次是让你选择保存路径和文件名称(默认是“无标题.txt”)。然后,将选择内容存入filename(这里我不知道怎么搞了一个存入f的冗余步骤,不过暂时不管它了)。然后呢,同样地,获取文件后缀、保存输入框内容,接下来就是写入环节。这里,我们判断如何写入。如果是py文件、bat文件等程序文件,我们当然不能把它们加密,不然就不能运行了,于是,我们就使用最为通用的utf-8编码给它写入。但如果是其他的文件,秉着安全第一的理念,我们就得用加密函数来给内容上一个保险,然后将内容写入。当然,保存完成后,“无标题”的大字就不能出现在窗口上方了,我们要把它改为另存为的程序的名称。

  def  opened(files):  global  filename,kkk
ff
= ' \n ' .join((item.decode( ' gbk ' ) for item in files))
filename
= ff if filename == "" :
filename
= None else :
top.title(os.path.basename(filename)
+ " - 加密文本编辑器 " )
format
= os.path.basename(filename)[os.path.basename(filename).find( " . " ) + 1 :]
textPad.delete(
1.0 , END) try :
f
= open(filename, ' rb ' )
c
= f.read()
ccc
= str(c)[2:-1 ]
ccc.replace(
" \\ " , "" )
textPad.insert(
1.0 , decrypt(ccc, format))
kkk
= 1
except :
f.close()
try :
f
= open(filename, ' r ' , encoding= " gbk " ) try :
c
= f.read() except :
f.close()
f
= open(filename, ' r ' , encoding= " utf-8 " )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0 except :
f.close()
f
= open(filename, ' rb ' )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0
f.close()

最后,是opened。细心的人会发现,这不就是myopen嘛!的确,两个函数很像,可以说是像极了。区别是,它会获取拖动到该窗口的文件的路径信息(这个信息原本在输入的files中),这个步骤代替了askopenfilename()函数。其他部分,两者的确一模一样。

 top = Tk()
top.title(
" 无标题 - 加密文本编辑器 " )
top.geometry(
" 1000x600+100+50 " )

menubar
= Menu(top)
menubar.add_command(label
= " 新建 " , command= mynew)
menubar.add_command(label
= " 打开 " , command= myopen)
menubar.add_command(label
= " 保存 " , command= mysave)
menubar.add_command(label
= " 另存为 " , command= mysaveas)

menu
= Menu(top, tearoff= False)
menu.add_command(label
= " 新建 " , accelerator= " Ctrl+N " , command= mynew)
menu.add_command(label
= " 打开 " , accelerator= " Ctrl+O " , command= myopen)
menu.add_command(label
= " 保存 " , accelerator= " Ctrl+S " , command= mysave)
menu.add_command(label
= " 另存为 " , accelerator= " Ctrl+Shift+S " , command=mysaveas)

这里嘛,就是搭建tkinter窗口的主要构建。这里没什么讲的,都是一些基本操作。唯一值得一提的是,“accelerator=”是设置快捷键。但遗憾的是,它只会显示快捷键名称,仍然需要手动绑定,不然无法使用。

这个是弹出菜单的弹出代码:

  def  command(event):
menu.post(event.x_root, event.y_root)

另一些窗口设置:

 top[ '  menu  ' ] = menubar
all
= Frame(top)
all.pack(expand
=YES, fill= BOTH)
textPad
= Text(all,font=( ' 宋体 ' , 14), undo=True)
 if  filename ==  ""  :
filename
= None
textPad.insert(
1.0, "" ) else :
top.title(os.path.basename(filename)
+ " - 加密文本编辑器 " )
format
= os.path.basename(filename)[os.path.basename(filename).find( " . " ) + 1 :]
textPad.delete(
1.0 , END) try :
f
= open(filename, ' rb ' )
c
= f.read()
ccc
= str(c)[2:-1 ]
ccc.replace(
" \\ " , "" )
textPad.insert(
1.0 , decrypt(ccc, format))
kkk
= 1 except :
f.close()
try :
f
= open(filename, ' r ' , encoding= " gbk " ) try :
c
= f.read() except :
f.close()
f
= open(filename, ' r ' , encoding= " utf-8 " )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0 except :
f.close()
f
= open(filename, ' rb ' )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0
f.close()

这个是不是又很熟悉呢?没错,又是打开文件。这就和开头的“sys.argv[1]”相对应,是用于Open with的。网上类似记事本的程序真不少,但有这一功能的,我似乎至今没有见到过。

 scroll = Scrollbar(all)
textPad.config(yscrollcommand
= scroll.set)
scroll.config(command
= textPad.yview)
scroll.pack(side
=RIGHT, fill= Y)
textPad.pack(expand
=YES,side=RIGHT,fill=BOTH)

又是窗口组件……(话说我为啥要分这么多段来设置窗口啊!!!(抓狂!))

 top.bind( "  <Control-N>  "  , mynew)
top.bind(
" <Control-n> " , mynew)
top.bind(
" <Control-O> " , myopen)
top.bind(
" <Control-o> " , myopen)
top.bind(
" <Control-S> " , mysave)
top.bind(
" <Control-s> " , mysave)
top.bind(
" <Control-Shift-S> " , mysaveas)
top.bind(
" <Control-Shift-s> " , mysaveas)
top.bind(
" <Button-3> " , command)

windnd.hook_dropfiles(top,func
=opened)

一些绑定,以及与opened相对应的事件判定。总而言之,都是和事件有关的一些东西。

啊,越讲越上头,超过了我预期的篇幅……好了,终于完结了!原本打算花一个月的,尽然一天就搞定了!这样也好,毕竟作为一个初二学生,和电脑真的是……很没有缘分。

最后,一段代码送给我自己,也送给每一位读者:

 top.mainloop() #对于代码是结束,对于程序仅仅是开始 

完整的代码:


 #  coding:utf-8

from tkinter import *
from tkinter.filedialog import *
from tkinter.messagebox import *
import windnd import os import sys
kkk
=1
try :
filename
= sys.argv[1 ] except :
filename
= ""


def encryption(c, d):
c
= list(c + d)
g
= list(d)
d
= 0 for i in g:
d
*= ord(i)
d
=round(abs(d)**0.5 )
f
= " 0x "
for i in c:
e
=str(ord(i)+ d)
d
=round(300*(d**0.5 ))
f
=f+e+ " a " f =eval(f[:-1 ]) return (f)
def decrypt(c,d):
c
= hex(int(c)) print (c)
c
=c[2:].split( " a " )
z
= d
g
= list(d)
d
= 0 for i in g:
d
*= ord(i)
d
= round(abs(d) ** 0.5 )
f
= ""
for i in c:
e
= chr(int(i)- d)
d
= round(300 * (d ** 0.5 ))
f
= f + e if f[-len(z):]== z:
f
=f[:- len(z)] return (f) else :
c
= " bbc " +12
def mynew(aaa=1 ): global top, filename, textPad
top.title(
" 无标题 - 加密文本编辑器 " )
filename
= None
textPad.delete(
1.0 , END)
textPad.insert(
1.0, "" )
def myopen(aaa=1 ): global filename,kkk
filename
= askopenfilename() if filename == "" :
filename
= None else :
top.title(os.path.basename(filename)
+ " - 加密文本编辑器 " )
format
=os.path.basename(filename)[os.path.basename(filename).find( " . " )+1 :]
textPad.delete(
1.0 , END) try :
f
= open(filename, ' rb ' )
c
= f.read()
ccc
= str(c)[2:-1 ]
ccc.replace(
" \\ " , "" )
textPad.insert(
1.0 ,decrypt(ccc,format))
kkk
=1
except :
f.close()
try :
f
= open(filename, ' r ' , encoding= " gbk " ) try :
c
= f.read() except :
f.close()
f
= open(filename, ' r ' , encoding= " utf-8 " )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0 except :
f.close()
f
= open(filename, ' rb ' )
c
= f.read()
textPad.insert(
1.0 , c)
kkk
= 0
f.close()
def mysave(aaa=1 ): global filename,kkk try :
msg
= textPad.get(1.0, ' end 标签: python

添加新评论