Update Picocrypt.py
This commit is contained in:
parent
5b71a4dccc
commit
ff5c7ce603
|
@ -56,9 +56,9 @@ kept = False
|
||||||
working = False
|
working = False
|
||||||
gMode = None
|
gMode = None
|
||||||
headerRsc = None
|
headerRsc = None
|
||||||
draggedFiles = False
|
allFiles = False
|
||||||
draggedFolderPaths = False
|
draggedFolderPaths = False
|
||||||
filesToErase = False
|
files = False
|
||||||
adString = "File metadata (used to store some text along with the file):"
|
adString = "File metadata (used to store some text along with the file):"
|
||||||
compressingNotice = "Compressing files together..."
|
compressingNotice = "Compressing files together..."
|
||||||
passwordNotice = "Error. The provided password is incorrect."
|
passwordNotice = "Error. The provided password is incorrect."
|
||||||
|
@ -96,29 +96,20 @@ s = tkinter.ttk.Style()
|
||||||
s.configure("TCheckbutton",background="#f5f6f7")
|
s.configure("TCheckbutton",background="#f5f6f7")
|
||||||
|
|
||||||
# Event when user selects an input file
|
# Event when user selects an input file
|
||||||
def inputSelected(draggedFile=None):
|
def inputSelected(draggedFile):
|
||||||
global inputFile,working,headerRsc,draggedFiles
|
global inputFile,working,headerRsc,allFiles
|
||||||
global draggedFolderPaths,filesToErase
|
global draggedFolderPaths,files
|
||||||
dummy.focus()
|
dummy.focus()
|
||||||
status.config(cursor="")
|
status.config(cursor="")
|
||||||
status.bind("<Button-1>",lambda e:None)
|
status.bind("<Button-1>",lambda e:None)
|
||||||
|
|
||||||
# Try to handle when select file is cancelled
|
# Try to handle when select file is cancelled
|
||||||
try:
|
try:
|
||||||
draggedFiles = None
|
allFiles = []
|
||||||
filesToErase = None
|
files = []
|
||||||
draggedFolderPaths = []
|
draggedFolderPaths = []
|
||||||
# Ask for input file
|
# Ask for input file
|
||||||
suffix = ""
|
suffix = ""
|
||||||
if not draggedFile:
|
|
||||||
tmp = filedialog.askopenfilename(
|
|
||||||
initialdir=expanduser("~")
|
|
||||||
)
|
|
||||||
if len(tmp)==0:
|
|
||||||
# Exception will be caught by except below
|
|
||||||
raise Exception("No file selected.")
|
|
||||||
inputFile = tmp
|
|
||||||
else:
|
|
||||||
tmp = [i for i in draggedFile]
|
tmp = [i for i in draggedFile]
|
||||||
res = []
|
res = []
|
||||||
within = False
|
within = False
|
||||||
|
@ -131,7 +122,6 @@ def inputSelected(draggedFile=None):
|
||||||
res.append(tmpName)
|
res.append(tmpName)
|
||||||
tmpName = ""
|
tmpName = ""
|
||||||
else:
|
else:
|
||||||
print(tmpName)
|
|
||||||
if i==" " and not within:
|
if i==" " and not within:
|
||||||
if tmpName!="":
|
if tmpName!="":
|
||||||
res.append(tmpName)
|
res.append(tmpName)
|
||||||
|
@ -141,28 +131,26 @@ def inputSelected(draggedFile=None):
|
||||||
if tmpName:
|
if tmpName:
|
||||||
res.append(tmpName)
|
res.append(tmpName)
|
||||||
|
|
||||||
draggedFiles = []
|
allFiles = []
|
||||||
filesToErase = []
|
files = []
|
||||||
|
|
||||||
for i in res:
|
for i in res:
|
||||||
if isdir(i):
|
if isdir(i):
|
||||||
draggedFolderPaths.append(i)
|
draggedFolderPaths.append(i)
|
||||||
tmp = Path(i).rglob("*")
|
tmp = Path(i).rglob("*")
|
||||||
for p in tmp:
|
for p in tmp:
|
||||||
draggedFiles.append(abspath(p))
|
allFiles.append(abspath(p))
|
||||||
else:
|
else:
|
||||||
filesToErase.append(i)
|
files.append(i)
|
||||||
|
|
||||||
draggedFiles = list(filter(lambda i:not isdir(i),draggedFiles))
|
if len(files)==1 and len(allFiles)==0:
|
||||||
|
inputFile = files[0]
|
||||||
if len(draggedFiles)==1:
|
files = []
|
||||||
draggedFiles = []
|
|
||||||
inputFile = draggedFiles[0]
|
|
||||||
else:
|
else:
|
||||||
inputFile = ""
|
inputFile = ""
|
||||||
|
|
||||||
# Decide if encrypting or decrypting
|
# Decide if encrypting or decrypting
|
||||||
if ".pcv" in inputFile.split("/")[-1]:
|
if inputFile.endswith(".pcv"):
|
||||||
suffix = " (will decrypt)"
|
suffix = " (will decrypt)"
|
||||||
fin = open(inputFile,"rb")
|
fin = open(inputFile,"rb")
|
||||||
|
|
||||||
|
@ -214,9 +202,9 @@ def inputSelected(draggedFile=None):
|
||||||
cpasswordString.set("Confirm password:")
|
cpasswordString.set("Confirm password:")
|
||||||
|
|
||||||
# Show selected file(s)
|
# Show selected file(s)
|
||||||
if draggedFiles:
|
if allFiles or files:
|
||||||
inputString.set(f"{len(draggedFiles)} file(s) selected"+
|
inputString.set(f"{len(allFiles) or len(files)}"+
|
||||||
" (will encrypt).")
|
" file(s) selected (will encrypt).")
|
||||||
else:
|
else:
|
||||||
inputString.set(inputFile.split("/")[-1]+suffix)
|
inputString.set(inputFile.split("/")[-1]+suffix)
|
||||||
|
|
||||||
|
@ -234,7 +222,7 @@ def inputSelected(draggedFile=None):
|
||||||
|
|
||||||
# No file selected, do nothing
|
# No file selected, do nothing
|
||||||
except:
|
except:
|
||||||
inputString.set("Please select a file.")
|
inputString.set("Please drag and drop files here.")
|
||||||
resetUI()
|
resetUI()
|
||||||
|
|
||||||
# Focus the dummy button to remove ugly borders
|
# Focus the dummy button to remove ugly borders
|
||||||
|
@ -244,28 +232,19 @@ def inputSelected(draggedFile=None):
|
||||||
|
|
||||||
# Allow drag and drop
|
# Allow drag and drop
|
||||||
def onDrop(e):
|
def onDrop(e):
|
||||||
print(e.data)
|
|
||||||
inputSelected(e.data)
|
inputSelected(e.data)
|
||||||
tk.drop_target_register(DND_FILES)
|
tk.drop_target_register(DND_FILES)
|
||||||
tk.dnd_bind("<<Drop>>",onDrop)
|
tk.dnd_bind("<<Drop>>",onDrop)
|
||||||
|
|
||||||
# Button to select input file
|
|
||||||
selectFileInput = tkinter.ttk.Button(
|
|
||||||
tk,
|
|
||||||
text="Select file",
|
|
||||||
command=inputSelected,
|
|
||||||
)
|
|
||||||
selectFileInput.place(x=19,y=20)
|
|
||||||
|
|
||||||
# Label that displays selected input file
|
# Label that displays selected input file
|
||||||
inputString = tkinter.StringVar(tk)
|
inputString = tkinter.StringVar(tk)
|
||||||
inputString.set("Please select a file.")
|
inputString.set("Please drag and drop files here.")
|
||||||
selectedInput = tkinter.ttk.Label(
|
selectedInput = tkinter.ttk.Label(
|
||||||
tk,
|
tk,
|
||||||
textvariable=inputString
|
textvariable=inputString
|
||||||
)
|
)
|
||||||
selectedInput.config(background="#f5f6f7")
|
selectedInput.config(background="#f5f6f7")
|
||||||
selectedInput.place(x=104,y=23)
|
selectedInput.place(x=17,y=20)
|
||||||
|
|
||||||
# Label that prompts user to enter a password
|
# Label that prompts user to enter a password
|
||||||
passwordString = tkinter.StringVar(tk)
|
passwordString = tkinter.StringVar(tk)
|
||||||
|
@ -323,7 +302,7 @@ cpasswordInput["state"] = "disabled"
|
||||||
# Start the encryption/decryption process
|
# Start the encryption/decryption process
|
||||||
def start():
|
def start():
|
||||||
global inputFile,outputFile,password,ad,kept
|
global inputFile,outputFile,password,ad,kept
|
||||||
global working,gMode,headerRsc,draggedFiles,filesToErase
|
global working,gMode,headerRsc,allFiles,files
|
||||||
global dragFolderPath
|
global dragFolderPath
|
||||||
dummy.focus()
|
dummy.focus()
|
||||||
reedsolo = False
|
reedsolo = False
|
||||||
|
@ -377,15 +356,20 @@ def start():
|
||||||
rsc = RSCodec(13)
|
rsc = RSCodec(13)
|
||||||
|
|
||||||
# Compress files together if user dragged multiple files
|
# Compress files together if user dragged multiple files
|
||||||
if draggedFiles:
|
if allFiles or files:
|
||||||
statusString.set(compressingNotice)
|
statusString.set(compressingNotice)
|
||||||
tmp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
tmp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
zfPath = Path(draggedFiles[0]).parent.absolute()
|
if files:
|
||||||
|
zfPath = Path(files[0]).parent.absolute()
|
||||||
|
else:
|
||||||
|
zfPath = Path(dirname(allFiles[0])).parent.absolute()
|
||||||
zfOffset = len(str(zfPath))
|
zfOffset = len(str(zfPath))
|
||||||
zfName = pathJoin(zfPath,tmp+".zip")
|
zfName = pathJoin(zfPath,tmp+".zip")
|
||||||
zf = ZipFile(zfName,"w")
|
zf = ZipFile(zfName,"w")
|
||||||
for i in draggedFiles:
|
for i in allFiles:
|
||||||
zf.write(i,i[zfOffset:])
|
zf.write(i,i[zfOffset:])
|
||||||
|
for i in files:
|
||||||
|
zf.write(i,pathSplit(i)[1])
|
||||||
|
|
||||||
zf.close()
|
zf.close()
|
||||||
inputFile = zfName
|
inputFile = zfName
|
||||||
|
@ -403,7 +387,13 @@ def start():
|
||||||
wipe = erase.get()==1
|
wipe = erase.get()==1
|
||||||
|
|
||||||
# Open files
|
# Open files
|
||||||
|
try:
|
||||||
fin = open(inputFile,"rb")
|
fin = open(inputFile,"rb")
|
||||||
|
except:
|
||||||
|
resetEncryptionUI()
|
||||||
|
statusString.set("Folder is empty.")
|
||||||
|
return
|
||||||
|
|
||||||
if reedsolo and mode=="decrypt":
|
if reedsolo and mode=="decrypt":
|
||||||
# Move pointer one forward
|
# Move pointer one forward
|
||||||
fin.read(1)
|
fin.read(1)
|
||||||
|
@ -714,39 +704,33 @@ def start():
|
||||||
fout.close()
|
fout.close()
|
||||||
fin.close()
|
fin.close()
|
||||||
|
|
||||||
print(draggedFolderPaths)
|
|
||||||
print(draggedFiles)
|
|
||||||
print(filesToErase)
|
|
||||||
input()
|
|
||||||
# Securely wipe files as necessary
|
# Securely wipe files as necessary
|
||||||
if wipe:
|
if wipe:
|
||||||
if draggedFolderPaths:
|
if draggedFolderPaths:
|
||||||
for i in draggedFolderPaths:
|
for i in draggedFolderPaths:
|
||||||
secureWipe(i)
|
secureWipe(i)
|
||||||
if filesToErase:
|
if files:
|
||||||
for i in range(len(filesToErase)):
|
for i in range(len(files)):
|
||||||
statusString.set(erasingNotice+f" ({i}/{len(filesToErase)}")
|
statusString.set(erasingNotice+f" ({i}/{len(files)}")
|
||||||
progress["value"] = i/len(filesToErase)
|
progress["value"] = i/len(files)
|
||||||
print("Erasing file "+filesToErase[i])
|
secureWipe(files[i])
|
||||||
secureWipe(filesToErase[i])
|
|
||||||
secureWipe(inputFile)
|
secureWipe(inputFile)
|
||||||
# Secure wipe not enabled
|
# Secure wipe not enabled
|
||||||
else:
|
else:
|
||||||
if draggedFiles:
|
if allFiles:
|
||||||
# Remove temporary zip file if created
|
# Remove temporary zip file if created
|
||||||
remove(inputFile)
|
remove(inputFile)
|
||||||
|
|
||||||
# Show appropriate notice if file corrupted or modified
|
# Show appropriate notice if file corrupted or modified
|
||||||
if not kept:
|
if not kept:
|
||||||
if mode=="encrypt":
|
statusString.set(f"Completed. (Click here to show output)")
|
||||||
output = inputFile.split("/")[-1]+".pcv"
|
|
||||||
else:
|
|
||||||
output = inputFile.split("/")[-1].replace(".pcv","")
|
|
||||||
statusString.set(f"Completed. (Output: {output})")
|
|
||||||
# Show Reed-Solomon stats if it fixed corrupted bytes
|
# Show Reed-Solomon stats if it fixed corrupted bytes
|
||||||
if mode=="decrypt" and reedsolo and reedsoloFixedCount:
|
if mode=="decrypt" and reedsolo and reedsoloFixedCount:
|
||||||
statusString.set(f"Completed with {reedsoloFixedCount} bytes fixed."+
|
statusString.set(
|
||||||
f" (Output: {output})")
|
f"Completed with {reedsoloFixedCount}"+
|
||||||
|
f" bytes fixed. (Output: {output})"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
if kept=="modified":
|
if kept=="modified":
|
||||||
statusString.set(kModifiedNotice)
|
statusString.set(kModifiedNotice)
|
||||||
|
@ -756,7 +740,13 @@ def start():
|
||||||
statusString.set(kVeryCorruptedNotice)
|
statusString.set(kVeryCorruptedNotice)
|
||||||
|
|
||||||
status.config(cursor="hand2")
|
status.config(cursor="hand2")
|
||||||
status.bind("<Button-1>",lambda e:print(outputPath))
|
|
||||||
|
# A little hack since strings are immutable
|
||||||
|
output = "".join([i for i in outputFile])
|
||||||
|
# Bind the output file
|
||||||
|
status.bind("<Button-1>",
|
||||||
|
lambda e:showOutput(output.replace("/","\\"))
|
||||||
|
)
|
||||||
|
|
||||||
# Reset variables and UI states
|
# Reset variables and UI states
|
||||||
resetUI()
|
resetUI()
|
||||||
|
@ -766,7 +756,7 @@ def start():
|
||||||
ad = ""
|
ad = ""
|
||||||
kept = False
|
kept = False
|
||||||
working = False
|
working = False
|
||||||
draggedFiles = False
|
allFiles = False
|
||||||
dragFolderPath = False
|
dragFolderPath = False
|
||||||
|
|
||||||
# Wipe keys for safety
|
# Wipe keys for safety
|
||||||
|
@ -799,7 +789,6 @@ def startWorker():
|
||||||
|
|
||||||
# Securely wipe file
|
# Securely wipe file
|
||||||
def secureWipe(fin):
|
def secureWipe(fin):
|
||||||
global draggedFiles
|
|
||||||
statusString.set(erasingNotice)
|
statusString.set(erasingNotice)
|
||||||
# Check platform, erase accordingly
|
# Check platform, erase accordingly
|
||||||
if platform.system()=="Windows":
|
if platform.system()=="Windows":
|
||||||
|
@ -812,20 +801,19 @@ def secureWipe(fin):
|
||||||
statusString.set(erasingNotice+f" ({i}/{len(paths)})")
|
statusString.set(erasingNotice+f" ({i}/{len(paths)})")
|
||||||
progress["value"] = 100*i/len(paths)
|
progress["value"] = 100*i/len(paths)
|
||||||
system(f'cd "{paths[i]}" && "{rootDir}/sdelete64.exe" * -p 4 -s -nobanner')
|
system(f'cd "{paths[i]}" && "{rootDir}/sdelete64.exe" * -p 4 -s -nobanner')
|
||||||
system(f'cd "{i}"')
|
system(f'cd "{rootDir}"')
|
||||||
rmtree(fin)
|
rmtree(fin)
|
||||||
else:
|
else:
|
||||||
statusString.set(erasingNotice)
|
statusString.set(erasingNotice)
|
||||||
progress["value"] = 100
|
progress["value"] = 100
|
||||||
system(f'sdelete64.exe "{fin}" -p 4 -nobanner')
|
system(f'sdelete64.exe "{fin}" -p 4 -nobanner')
|
||||||
elif platform.system()=="Darwin":
|
elif platform.system()=="Darwin":
|
||||||
pass
|
system(f'rm -rfP "{fin}"')
|
||||||
else:
|
else:
|
||||||
system(f'shred -uz "{fin}" -n 4')
|
system(f'shred -uz "{fin}" -n 4')
|
||||||
|
|
||||||
# Disable all inputs while encrypting/decrypting
|
# Disable all inputs while encrypting/decrypting
|
||||||
def disableAllInputs():
|
def disableAllInputs():
|
||||||
selectFileInput["state"] = "disabled"
|
|
||||||
passwordInput["state"] = "disabled"
|
passwordInput["state"] = "disabled"
|
||||||
cpasswordInput["state"] = "disabled"
|
cpasswordInput["state"] = "disabled"
|
||||||
adArea["state"] = "disabled"
|
adArea["state"] = "disabled"
|
||||||
|
@ -837,7 +825,6 @@ def disableAllInputs():
|
||||||
# Reset UI to encryption state
|
# Reset UI to encryption state
|
||||||
def resetEncryptionUI():
|
def resetEncryptionUI():
|
||||||
global working
|
global working
|
||||||
selectFileInput["state"] = "normal"
|
|
||||||
passwordInput["state"] = "normal"
|
passwordInput["state"] = "normal"
|
||||||
cpasswordInput["state"] = "normal"
|
cpasswordInput["state"] = "normal"
|
||||||
adArea["state"] = "normal"
|
adArea["state"] = "normal"
|
||||||
|
@ -845,12 +832,13 @@ def resetEncryptionUI():
|
||||||
eraseBtn["state"] = "normal"
|
eraseBtn["state"] = "normal"
|
||||||
rsBtn["state"] = "normal"
|
rsBtn["state"] = "normal"
|
||||||
working = False
|
working = False
|
||||||
|
progress.stop()
|
||||||
|
progress.config(mode="determinate")
|
||||||
progress["value"] = 100
|
progress["value"] = 100
|
||||||
|
|
||||||
# Reset UI to decryption state
|
# Reset UI to decryption state
|
||||||
def resetDecryptionUI():
|
def resetDecryptionUI():
|
||||||
global working
|
global working
|
||||||
selectFileInput["state"] = "normal"
|
|
||||||
passwordInput["state"] = "normal"
|
passwordInput["state"] = "normal"
|
||||||
adArea["state"] = "normal"
|
adArea["state"] = "normal"
|
||||||
startBtn["state"] = "normal"
|
startBtn["state"] = "normal"
|
||||||
|
@ -862,7 +850,6 @@ def resetDecryptionUI():
|
||||||
|
|
||||||
# Reset UI to original state (no file selected)
|
# Reset UI to original state (no file selected)
|
||||||
def resetUI():
|
def resetUI():
|
||||||
selectFileInput["state"] = "normal"
|
|
||||||
adArea["state"] = "normal"
|
adArea["state"] = "normal"
|
||||||
adArea.delete("1.0",tkinter.END)
|
adArea.delete("1.0",tkinter.END)
|
||||||
adArea["state"] = "disabled"
|
adArea["state"] = "disabled"
|
||||||
|
@ -875,7 +862,7 @@ def resetUI():
|
||||||
cpasswordInput["state"] = "disabled"
|
cpasswordInput["state"] = "disabled"
|
||||||
cpasswordString.set("Confirm password:")
|
cpasswordString.set("Confirm password:")
|
||||||
progress["value"] = 0
|
progress["value"] = 0
|
||||||
inputString.set("Please select a file.")
|
inputString.set("Please drag and drop files here.")
|
||||||
keepBtn["state"] = "normal"
|
keepBtn["state"] = "normal"
|
||||||
keep.set(0)
|
keep.set(0)
|
||||||
keepBtn["state"] = "disabled"
|
keepBtn["state"] = "disabled"
|
||||||
|
@ -888,6 +875,15 @@ def resetUI():
|
||||||
progress.config(mode="determinate")
|
progress.config(mode="determinate")
|
||||||
progress["value"] = 0
|
progress["value"] = 0
|
||||||
|
|
||||||
|
def showOutput(file):
|
||||||
|
if platform.system()=="Windows":
|
||||||
|
system(f'explorer /select,"{file}"')
|
||||||
|
elif platform.system()=="Darwin":
|
||||||
|
system(f'cd "{file}"; open -R .')
|
||||||
|
system(f'cd "{rootDir}"')
|
||||||
|
else:
|
||||||
|
system(f'xdg-open "{dirname(file)}"')
|
||||||
|
|
||||||
# ad stands for "associated data"/metadata
|
# ad stands for "associated data"/metadata
|
||||||
adLabelString = tkinter.StringVar(tk)
|
adLabelString = tkinter.StringVar(tk)
|
||||||
adLabelString.set(adString)
|
adLabelString.set(adString)
|
||||||
|
|
Loading…
Reference in New Issue