Encode / Decode (GUI)

Share your advanced PureBasic knowledge/code with the community.
AZJIO
Addict
Addict
Posts: 2171
Joined: Sun May 14, 2017 1:48 am

Encode / Decode (GUI)

Post by AZJIO »

Encode / Decode - encrypt files
Download: yandex
Image

Code: Select all

;- TOP
; AZJIO 17.04.2025

EnableExplicit

Define UserIntLang, *Lang
If OpenLibrary(0, "kernel32.dll")
	*Lang = GetFunction(0, "GetUserDefaultUILanguage")
	If *Lang
		UserIntLang = CallFunctionFast(*Lang)
	EndIf
	CloseLibrary(0)
EndIf

;- Language
#CountStrLang = 11
Global Dim Lng.s(#CountStrLang)
Lng(0) = "Encode / Decode"
Lng(1) = "To the new file"
Lng(2) = "Enter the password"
Lng(3) = "Enter the path or drag the file into the input field"
Lng(4) = "Manual"
Lng(5) = "Auto Encoding"
Lng(6) = "Auto Decoding"
Lng(7) = "Encode"
Lng(8) = "Decode"
Lng(9) = "Message"
Lng(10) = "The path does not exist"
Lng(11) = "No password"

If UserIntLang = 1049 ; ru
	Lng(0) = "Кодировать / декодировать"
	Lng(1) = "В новый файл"
	Lng(2) = "Введите пароль"
	Lng(3) = "Введите путь или перетащите файл в поле ввода"
	Lng(4) = "Ручной"
	Lng(5) = "Автокодирование"
	Lng(6) = "Автодекодирование"
	Lng(7) = "Кодировать"
	Lng(8) = "Декодировать"
	Lng(9) = "Сообщение"
	Lng(10) = "Путь не существует"
	Lng(11) = "Отсутствует пароль"
EndIf

;- # Constants
#Window = 0

Enumeration
	#StatusBar
	#btn1
	#btnOpen
	#chNewFile
	#strPass
	#strPath
	#cmbx6
	#btnDecoder
	#btnEncoder
EndEnumeration

Enumeration
	#FontNorm
	#FontGrey
EndEnumeration

;- ● Declare
Declare EncoderDecoder(Decoder = 0)
Declare ReadFileToPtr(Path$)
Declare SaveFile_Buff(File.s, *Buff, Size)
Declare SizeHandler()

;- ● Global
Global hPass, hPath, tmp$

;-┌──GUI──┐
OpenWindow(#Window, 0,0, 420, 140, Lng(0), #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)

TextGadget(#StatusBar, 180, 73, 230, 27, "", #PB_Text_Border)
; ButtonGadget(#btn1, 160, 80, 150, 17, "")
ButtonGadget(#btnOpen, 384, 39, 28, 27, Chr($2026))
CheckBoxGadget(#chNewFile, 10, 75, 169, 22, Lng(1))
SetGadgetState(#chNewFile, #PB_Checkbox_Checked)

StringGadget(#strPass, 10, 8, 400, 25, Lng(2))
StringGadget(#strPath, 10, 40, 374, 25, Lng(3))

ComboBoxGadget(#cmbx6, 10, 108, 160, 28)
AddGadgetItem(#cmbx6, 0, Lng(4))
AddGadgetItem(#cmbx6, 1, Lng(5))
AddGadgetItem(#cmbx6, 2, Lng(6))
SetGadgetState(#cmbx6, 0)

ButtonGadget(#btnEncoder, 180, 108, 100, 27, Lng(7))
ButtonGadget(#btnDecoder, 290, 108, 120, 27, Lng(8))

hPass = GadgetID(#strPass)
hPath = GadgetID(#strPath)

EnableGadgetDrop(#strPath, #PB_Drop_Files, #PB_Drag_Copy)

LoadFont(#FontGrey, "", 0, #PB_Font_Italic)
LoadFont(#FontNorm, "", 0)
SetGadgetFont(#strPass, FontID(#FontGrey))
SetGadgetFont(#strPath, FontID(#FontGrey))
SetGadgetColor(#strPass, #PB_Gadget_FrontColor, $666666)
SetGadgetColor(#strPath, #PB_Gadget_FrontColor, $666666)

BindEvent(#PB_Event_SizeWindow, @SizeHandler())
WindowBounds(#Window, 420, 140, #PB_Ignore, #PB_Ignore) 

;-┌──Loop──┐
Repeat
	Select WaitWindowEvent()
		Case #PB_Event_GadgetDrop
			Select EventGadget()
				Case #strPath
					tmp$ = EventDropFiles()
					If FileSize(tmp$) > 0
						SetGadgetColor(#strPath, #PB_Gadget_FrontColor, 0)
						SetGadgetFont(#strPath, FontID(#FontNorm))
						SetGadgetText(#strPath, tmp$)
						If GetGadgetState(#cmbx6) = 1
							EncoderDecoder()
						ElseIf GetGadgetState(#cmbx6) = 2
							EncoderDecoder(1)
						EndIf
					EndIf
			EndSelect
		Case #PB_Event_Gadget
			Select EventGadget()
					
				Case #btn1
					
				Case #btnOpen
					tmp$ = OpenFileRequester("", GetCurrentDirectory(), "(*.*)|*.*", 0)
					If Asc(tmp$)
						SetGadgetColor(#strPath, #PB_Gadget_FrontColor, 0)
						SetGadgetFont(#strPath, FontID(#FontNorm))
						SetGadgetText(#strPath, tmp$)
						If GetGadgetState(#cmbx6) = 1
							EncoderDecoder()
						ElseIf GetGadgetState(#cmbx6) = 2
							EncoderDecoder(1)
						EndIf
					EndIf
					
					
				Case #chNewFile
					
				Case #strPass
					Select EventType() 
						Case #PB_EventType_Change
							tmp$ = GetGadgetText(#strPass)
							If Asc(tmp$) And tmp$ <>Lng(3)
								SetGadgetColor(#strPass, #PB_Gadget_FrontColor, 0)
								SetGadgetFont(#strPass, FontID(#FontNorm))
							EndIf
						Case #PB_EventType_LostFocus
							If GetGadgetText(#strPass) = ""
								SetGadgetColor(#strPass, #PB_Gadget_FrontColor, $666666)
								SetGadgetFont(#strPass, FontID(#FontGrey))
								SetGadgetText(#strPass, Lng(2))
							EndIf
						Case #PB_EventType_Focus
							If GetGadgetText(#strPass) = Lng(2)
								SetGadgetColor(#strPass, #PB_Gadget_FrontColor, 0)
								SetGadgetFont(#strPass, FontID(#FontNorm))
								SetGadgetText(#strPass, "")
							EndIf
					EndSelect
				Case #strPath
					Select EventType() 
						Case #PB_EventType_Change
							tmp$ = GetGadgetText(#strPath)
							If Asc(tmp$) And tmp$ <>Lng(3)
								SetGadgetColor(#strPath, #PB_Gadget_FrontColor, 0)
								SetGadgetFont(#strPath, FontID(#FontNorm))
							EndIf
						Case #PB_EventType_LostFocus
							If GetGadgetText(#strPath) = ""
								SetGadgetColor(#strPath, #PB_Gadget_FrontColor, $666666)
								SetGadgetFont(#strPath, FontID(#FontGrey))
								SetGadgetText(#strPath, Lng(3))
							EndIf
						Case #PB_EventType_Focus
							If GetGadgetText(#strPath) = Lng(3)
								SetGadgetColor(#strPath, #PB_Gadget_FrontColor, 0)
								SetGadgetFont(#strPath, FontID(#FontNorm))
								SetGadgetText(#strPath, "")
							EndIf
					EndSelect
					
				Case #cmbx6
					
				Case #btnDecoder
					EncoderDecoder(1)
					
				Case #btnEncoder
; 					tmp$ = GetGadgetText(#strPath)
; 					If Asc(tmp$) And FileSize(tmp$) > 0
; 						Encoder()
; 					EndIf
					EncoderDecoder()
					
			EndSelect
		Case #PB_Event_CloseWindow
			CloseWindow(#Window)
			End
	EndSelect
ForEver
;-└──Loop──┘

Procedure.s GetCopyName(Path$, Mode = 0, Text$ = "Copy")
    Protected i, DirFile$, Ext$
    If FileSize(Path$) >= 0
        DirFile$ = GetPathPart(Path$) + GetFilePart(Path$, #PB_FileSystem_NoExtension)
        Ext$ = GetExtensionPart(Path$)
        i = 0
        If Mode
            Repeat
                i + 1
                Path$ = DirFile$ + "_" + i + "." + Ext$
            Until FileSize(Path$) < 0
        Else
            Repeat
                i + 1
                If i = 1
                    Path$ = DirFile$ + " " + Text$ + "." + Ext$
                Else
                    Path$ = DirFile$ + " " + Text$ + " (" + i + ")." + Ext$
                EndIf
            Until FileSize(Path$) < 0
        EndIf
    EndIf
    ProcedureReturn Path$
EndProcedure

Procedure.s GetKey(Pass$, mode = 0)
	Protected BLen, i
	Protected NewMap OneDupl()
	Protected *p0, *a.ASCII, *p.ASCII
	Protected p${8}
; 	Static p${8} ; можно было бы запомнить, но шифрация применяется редко и разово, поэтому нет смысла разделять и помнить
	*a = @p$
	If mode
		RandomSeed(285739)
	Else
		RandomSeed(937582)
	EndIf
	
	For i = 1 To 16
		*a\a = Random(255) ; генерация не содержит явный код в исходнике.
		*a + SizeOf(ASCII)
	Next
; 	Debug Len(p$)
; 	Debug PeekS(@p$, 8, #PB_Unicode)
; 	Debug p$
	BLen = StringByteLength(Pass$, #PB_Unicode)
	*p = @Pass$
	*p0 = *p
; 	pos = 0
	*a = @p$
	For i = 1 To 16
		While Not *p\a Or FindMapElement(OneDupl(), Chr(*p\a))
			If *p > *p0 + BLen
				Break 2
			EndIf
			*p + SizeOf(ASCII)
		Wend
		AddMapElement(OneDupl(), Chr(*p\a), #PB_Map_NoElementCheck)
; 		Debug 1
		*a\a = *p\a
		*a + SizeOf(ASCII)
		*p + SizeOf(ASCII)
	Next
	ProcedureReturn p$
EndProcedure


Procedure EncoderDecoder(Decoder = 0)
	Protected Pass$, Path$, SavePath$, *file, *Key, *InitializationVector, *output, size, success
	
	Pass$ = GetGadgetText(#strPass)
	Path$ = GetGadgetText(#strPath)

	If Not Asc(Path$) Or FileSize(Path$) < 0
		ProcedureReturn MessageRequester(Lng(9), Lng(10), #PB_MessageRequester_Ok) ; , WindowID(#Window)
	EndIf
	If Not Asc(Pass$)
		ProcedureReturn MessageRequester(Lng(9), Lng(11), #PB_MessageRequester_Ok)
	EndIf
	If GetGadgetState(#chNewFile) & #PB_Checkbox_Checked
		SavePath$ = GetCopyName(Path$, 1)
	EndIf
	*file = ReadFileToPtr(Path$)
	If *file
		size = MemorySize(*file)
		*output = AllocateMemory(size)
		If *output
			tmp$ = GetKey(Pass$)
			*Key = @tmp$
			tmp$ = GetKey(Pass$, 1)
			*InitializationVector = @tmp$
			If Decoder
				success = AESDecoder(*file, *output, size, *Key, 256, *InitializationVector, #PB_Cipher_CBC)
			Else
				success = AESEncoder(*file, *output, size, *Key, 256, *InitializationVector, #PB_Cipher_CBC)
			EndIf
			If success
				If Asc(SavePath$)
					Path$ = SavePath$
				EndIf
				If SaveFile_Buff(Path$, *output, size)
					SetGadgetText(#StatusBar, "Done")
				EndIf
			EndIf
			FreeMemory(*output)
		EndIf
		FreeMemory(*file)
	EndIf
EndProcedure

Procedure SaveFile_Buff(File.s, *Buff, Size)
	Protected Result = #False
	Protected ID = CreateFile(#PB_Any, File)
	If ID
		If WriteData(ID, *Buff, Size) = Size
			Result = #True
		EndIf
		CloseFile(ID)
	EndIf
	ProcedureReturn Result
EndProcedure


Procedure ReadFileToPtr(Path$)
	Protected id_file, length, *m, bytes
	
	id_file = ReadFile(#PB_Any, Path$)
	If id_file
		length = Lof(id_file)
		*m = AllocateMemory(length)
		If *m
			bytes = ReadData(id_file, *m, length)
			If bytes <> length
				FreeMemory(*m)
				*m = 0
			EndIf
		EndIf
		
		CloseFile(id_file)
	EndIf
	
	ProcedureReturn *m
EndProcedure

Procedure SizeHandler()
	Protected w, h, y, StepH
	w = WindowWidth(#Window)
	h = WindowHeight(#Window)
	StepH = h / 4 - 10
	ResizeGadget(#strPass, #PB_Ignore, #PB_Ignore, w - 20, StepH)
	y = 15 + StepH
    ResizeGadget(#strPath, #PB_Ignore, y, w - w / 15 - 18, StepH)
    ResizeGadget(#btnOpen, w - w / 15 - 8, y - 1, w / 15, StepH + 2)
	y = (11 + StepH) * 2 + 1
    ResizeGadget(#chNewFile, #PB_Ignore, y, w / 3, StepH)
    ResizeGadget(#StatusBar, w / 3 + 40, y, w / 3 * 2 - 50, StepH + 2)
    y = (11 + StepH) * 3
    StepH + 2
    ResizeGadget(#cmbx6, #PB_Ignore, y, w / 3 + 20, StepH)
    ResizeGadget(#btnEncoder, w / 3 + 40, y, w / 3 - 40, StepH)
    ResizeGadget(#btnDecoder, w / 3 * 2 + 10, y, w / 3 - 20, StepH)
EndProcedure
AZJIO
Addict
Addict
Posts: 2171
Joined: Sun May 14, 2017 1:48 am

Re: Encode / Decode (GUI)

Post by AZJIO »

Update
A command prompt has been added to add the program to the context menu of the file manager.
Added encryption in 10 MB blocks without loading the entire file into memory.
The key format has been changed - hash sum, instead of generating bytes.
The source code for Linux is still from the previous version

Update
Fix - I forgot about FinishCipher()
Added BinaryHex()

Discussion

Code: Select all

;- TOP
; AZJIO 20.04.2025

EnableExplicit

UseSHA3Fingerprint()

Define UserIntLang

CompilerSelect #PB_Compiler_OS
	CompilerCase #PB_OS_Windows
		Define *Lang
		If OpenLibrary(0, "kernel32.dll")
			*Lang = GetFunction(0, "GetUserDefaultUILanguage")
			If *Lang And CallFunctionFast(*Lang) = 1049 ; ru
				UserIntLang = 1
			EndIf
			CloseLibrary(0)
		EndIf
	CompilerCase #PB_OS_Linux
		If ExamineEnvironmentVariables()
			While NextEnvironmentVariable()
				If Left(EnvironmentVariableName(), 4) = "LANG" And Left(EnvironmentVariableValue(), 2) = "ru"
					UserIntLang = 1
					Break
				EndIf
			Wend
		EndIf
CompilerEndSelect

;- Language
#CountStrLang = 12
Global Dim Lng.s(#CountStrLang)
Lng(0) = "Encode / Decode"
Lng(1) = "To the new file"
Lng(2) = "Enter the password"
Lng(3) = "Enter the path or drag the file into the input field"
Lng(4) = "Manual"
Lng(5) = "Auto Encoding"
Lng(6) = "Auto Decoding"
Lng(7) = "Encode"
Lng(8) = "Decode"
Lng(9) = "Message"
Lng(10) = "The path does not exist"
Lng(11) = "No password"
Lng(12) = "Done, error="

If UserIntLang = 1 ; ru
	Lng(0) = "Кодировать / декодировать"
	Lng(1) = "В новый файл"
	Lng(2) = "Введите пароль"
	Lng(3) = "Введите путь или перетащите файл в поле ввода"
	Lng(4) = "Ручной"
	Lng(5) = "Автокодирование"
	Lng(6) = "Автодекодирование"
	Lng(7) = "Кодировать"
	Lng(8) = "Декодировать"
	Lng(9) = "Сообщение"
	Lng(10) = "Путь не существует"
	Lng(11) = "Отсутствует пароль"
	Lng(12) = "Готово, Ошибка="
EndIf

;- # Constants
#Window = 0

Enumeration
	#StatusBar
	#btnOpen
	#chNewFile
	#strPass
	#strPath
	#cmbx6
	#btnDecoder
	#btnEncoder
EndEnumeration

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
	Enumeration
		#FontNorm
		#FontGrey
	EndEnumeration
CompilerEndIf

;- ● Declare
Declare EncoderDecoder(Decoder = 0)
Declare SizeHandler()

;- ● Global
Global hPass, hPath, tmp$

;-┌──GUI──┐
OpenWindow(#Window, 0,0, 420, 140, Lng(0), #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)

TextGadget(#StatusBar, 180, 73, 230, 27, "", #PB_Text_Border)
; ButtonGadget(#btn1, 160, 80, 150, 17, "")
ButtonGadget(#btnOpen, 384, 39, 28, 27, Chr($2026))
CheckBoxGadget(#chNewFile, 10, 75, 169, 22, Lng(1))
SetGadgetState(#chNewFile, #PB_Checkbox_Checked)

StringGadget(#strPass, 10, 8, 400, 25, Lng(2))
StringGadget(#strPath, 10, 40, 374, 25, Lng(3))

ComboBoxGadget(#cmbx6, 10, 108, 160, 28)
AddGadgetItem(#cmbx6, 0, Lng(4))
AddGadgetItem(#cmbx6, 1, Lng(5))
AddGadgetItem(#cmbx6, 2, Lng(6))
SetGadgetState(#cmbx6, 0)

ButtonGadget(#btnEncoder, 180, 108, 100, 27, Lng(7))
ButtonGadget(#btnDecoder, 290, 108, 120, 27, Lng(8))

hPass = GadgetID(#strPass)
hPath = GadgetID(#strPath)

EnableGadgetDrop(#strPath, #PB_Drop_Files, #PB_Drag_Copy)

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
	LoadFont(#FontGrey, "", 0, #PB_Font_Italic)
	LoadFont(#FontNorm, "", 0)
	SetGadgetFont(#strPass, FontID(#FontGrey))
	SetGadgetFont(#strPath, FontID(#FontGrey))
	SetGadgetColor(#strPass, #PB_Gadget_FrontColor, $666666)
	SetGadgetColor(#strPath, #PB_Gadget_FrontColor, $666666)
CompilerEndIf

BindEvent(#PB_Event_SizeWindow, @SizeHandler())
WindowBounds(#Window, 420, 140, #PB_Ignore, #PB_Ignore)

; для контекстного меню
tmp$ = ProgramParameter()
If Asc(tmp$) And FileSize(tmp$) > -1
	SetGadgetText(#strPath, tmp$)
	CompilerIf #PB_Compiler_OS = #PB_OS_Windows
		SetGadgetColor(#strPath, #PB_Gadget_FrontColor, 0)
		SetGadgetFont(#strPath, FontID(#FontNorm))
	CompilerEndIf
EndIf

;-┌──Loop──┐
Repeat
	Select WaitWindowEvent()
		Case #PB_Event_GadgetDrop
			Select EventGadget()
				Case #strPath
					tmp$ = EventDropFiles()
					If FileSize(tmp$) > 0
						CompilerIf #PB_Compiler_OS = #PB_OS_Windows
							SetGadgetColor(#strPath, #PB_Gadget_FrontColor, 0)
							SetGadgetFont(#strPath, FontID(#FontNorm))
						CompilerEndIf
						SetGadgetText(#strPath, tmp$)
						If GetGadgetState(#cmbx6) = 1
							EncoderDecoder()
						ElseIf GetGadgetState(#cmbx6) = 2
							EncoderDecoder(1)
						EndIf
					EndIf
			EndSelect
		Case #PB_Event_Gadget
			Select EventGadget()
				Case #btnOpen
					tmp$ = OpenFileRequester("", GetCurrentDirectory(), "(*.*)|*.*", 0)
					If Asc(tmp$)
						CompilerIf #PB_Compiler_OS = #PB_OS_Windows
							SetGadgetColor(#strPath, #PB_Gadget_FrontColor, 0)
							SetGadgetFont(#strPath, FontID(#FontNorm))
						CompilerEndIf
						SetGadgetText(#strPath, tmp$)
						If GetGadgetState(#cmbx6) = 1
							EncoderDecoder()
						ElseIf GetGadgetState(#cmbx6) = 2
							EncoderDecoder(1)
						EndIf
					EndIf


; 			CompilerIf #PB_Compiler_OS = #PB_OS_Windows

				Case #strPass
					Select EventType()
						Case #PB_EventType_Change
							tmp$ = GetGadgetText(#strPass)
							If Asc(tmp$) And tmp$ <>Lng(3)
								SetGadgetColor(#strPass, #PB_Gadget_FrontColor, 0)
								SetGadgetFont(#strPass, FontID(#FontNorm))
							EndIf
						Case #PB_EventType_LostFocus
							If GetGadgetText(#strPass) = ""
								SetGadgetColor(#strPass, #PB_Gadget_FrontColor, $666666)
								SetGadgetFont(#strPass, FontID(#FontGrey))
								SetGadgetText(#strPass, Lng(2))
							EndIf
						Case #PB_EventType_Focus
							If GetGadgetText(#strPass) = Lng(2)
								SetGadgetColor(#strPass, #PB_Gadget_FrontColor, 0)
								SetGadgetFont(#strPass, FontID(#FontNorm))
								SetGadgetText(#strPass, "")
							EndIf
					EndSelect
				Case #strPath
					Select EventType()
						Case #PB_EventType_Change
							tmp$ = GetGadgetText(#strPath)
							If Asc(tmp$) And tmp$ <>Lng(3)
								SetGadgetColor(#strPath, #PB_Gadget_FrontColor, 0)
								SetGadgetFont(#strPath, FontID(#FontNorm))
							EndIf
						Case #PB_EventType_LostFocus
							If GetGadgetText(#strPath) = ""
								SetGadgetColor(#strPath, #PB_Gadget_FrontColor, $666666)
								SetGadgetFont(#strPath, FontID(#FontGrey))
								SetGadgetText(#strPath, Lng(3))
							EndIf
						Case #PB_EventType_Focus
							If GetGadgetText(#strPath) = Lng(3)
								SetGadgetColor(#strPath, #PB_Gadget_FrontColor, 0)
								SetGadgetFont(#strPath, FontID(#FontNorm))
								SetGadgetText(#strPath, "")
							EndIf
					EndSelect

; 				CompilerEndIf

				Case #btnDecoder
					EncoderDecoder(1)

				Case #btnEncoder
; 					tmp$ = GetGadgetText(#strPath)
; 					If Asc(tmp$) And FileSize(tmp$) > 0
; 						Encoder()
; 					EndIf
					EncoderDecoder()

			EndSelect
		Case #PB_Event_CloseWindow
			CloseWindow(#Window)
			End
	EndSelect
ForEver
;-└──Loop──┘

Procedure.s GetCopyName(Path$, Mode = 0, Text$ = "Copy")
    Protected i, DirFile$, Ext$
    If FileSize(Path$) >= 0
        DirFile$ = GetPathPart(Path$) + GetFilePart(Path$, #PB_FileSystem_NoExtension)
        Ext$ = GetExtensionPart(Path$)
        i = 0
        If Mode
            Repeat
                i + 1
                Path$ = DirFile$ + "_" + i + "." + Ext$
            Until FileSize(Path$) < 0
        Else
            Repeat
                i + 1
                If i = 1
                    Path$ = DirFile$ + " " + Text$ + "." + Ext$
                Else
                    Path$ = DirFile$ + " " + Text$ + " (" + i + ")." + Ext$
                EndIf
            Until FileSize(Path$) < 0
        EndIf
    EndIf
    ProcedureReturn Path$
EndProcedure

Structure CharStr
  StructureUnion
    c.c
    s.s{1}
  EndStructureUnion
EndStructure

Procedure BinaryHex(String$)
    Protected *m, *r.Ascii, *c.CharStr
    Protected tmp.s{3}
    Protected Size

    If Not Asc(String$) ; пустая строка
        ProcedureReturn -1
    EndIf
    Size = Len(String$)
    If Size & 1 ; нечётное число
        ProcedureReturn -2
    EndIf
    *c = @String$

    *m = AllocateMemory(Size / 2 + 2)
    If *m
        *r = *m
        ; 0-9 и a-f (только в нижнем регистре)
        While (*c\c > 47 And *c\c < 58) Or (*c\c > 96 And *c\c < 103) ; Or (*c\c > 64 And *c\c < 71) ; A-F верхний регистр не берём во внимание
            tmp = "$"
            tmp + *c\s
            *c + 2
            If *c\c
                tmp + *c\s
                *r\a = Val(tmp)
                *r + 1
                *c + 2
            Else ; повторная проверка чётности, нужна ли она
                FreeMemory(*m)
                ProcedureReturn -3
            EndIf
        Wend
        ; проверка дошли ли мы до конца строки, если не 0,
		; то не дошли и в строке есть не шестнадцатеричные символы
        If *c\c <> 0
            ProcedureReturn -4
        EndIf
        If *r > *m
            *r\a = 0
            ; Добавляем ещё 0, чтобы можно было использовать UTF8, UTF16
            *r + 1
            *r\a = 0
        EndIf
    EndIf

    ProcedureReturn *m
EndProcedure


Procedure EncoderDecoder(Decoder = 0)
	#blok = 10 * 1024 * 1024 ; 10 Mb
	#Cipher = 0
	#Bits = 256
	#File = 0
	#File2 = 1
	Protected Pass$, Path$, SavePath$, *Input, *Key, *InitializationVector, *output, tmp$, success, bytes, error

	Pass$ = GetGadgetText(#strPass) ; для короткого пароля всё же лучше сделать заполнитель. Хотя при дебагинге кода усложнитель не добавляет безопасности.
	Path$ = GetGadgetText(#strPath)

	If Not Asc(Path$) Or FileSize(Path$) < 0
		ProcedureReturn MessageRequester(Lng(9), Lng(10), #PB_MessageRequester_Ok) ; , WindowID(#Window)
	EndIf
	If Not Asc(Pass$)
		ProcedureReturn MessageRequester(Lng(9), Lng(11), #PB_MessageRequester_Ok)
	EndIf
	If GetGadgetState(#chNewFile) & #PB_Checkbox_Checked
		SavePath$ = GetCopyName(Path$, 1)
	EndIf

	*Input = AllocateMemory(#blok)
	If *Input
		*Output = AllocateMemory(#blok)
		If *Output
			If ReadFile(#File, Path$, #PB_File_SharedWrite)
				If Not Asc(SavePath$)
					SavePath$ = Path$ ; пишем в тот же файл.
				EndIf
				If OpenFile(#File2, SavePath$, #PB_File_SharedRead)
					tmp$ = StringFingerprint(Pass$, #PB_Cipher_SHA3, #Bits, #PB_Unicode)
					*Key = BinaryHex(tmp$)
					If *Key < 0 And *Key > -5
						*Key = Ascii(tmp$)
					EndIf
					*InitializationVector = Ascii(tmp$)
; 					*InitializationVector = *Key + 32 ; берём вторую половину хеша. Так как он 512 бит, как раз каждому по 256.
; 					Debug tmp$
; 					Debug PeekS(*Key, 32, #PB_Ascii)
; 					Debug PeekS(*InitializationVector, 32, #PB_Ascii)
					If Decoder
						success = StartAESCipher(#Cipher, *Key, #Bits , *InitializationVector, #PB_Cipher_Decode | #PB_Cipher_CBC)
					Else
						success = StartAESCipher(#Cipher, *Key, #Bits , *InitializationVector, #PB_Cipher_Encode | #PB_Cipher_CBC)
					EndIf
					If success
						While Eof(#File) = 0
							bytes = ReadData(#File, *Input, #blok)
							AddCipherBuffer(#Cipher, *Input, *Output, bytes)
							If WriteData(#File2, *Output, bytes) <> bytes
								error = 1
							EndIf
						Wend
						FinishCipher(#Cipher)
					EndIf
					FreeMemory(*Key)
					CloseFile(#File2)
				EndIf
				CloseFile(#File)
			EndIf
			FreeMemory(*output)
		EndIf
		FreeMemory(*Input)
	EndIf
	SetGadgetText(#StatusBar, Lng(12) + Str(error))
EndProcedure


Procedure SizeHandler()
	Protected w, h, y, StepH
	w = WindowWidth(#Window)
	h = WindowHeight(#Window)
	StepH = h / 4 - 10
	ResizeGadget(#strPass, #PB_Ignore, #PB_Ignore, w - 20, StepH)
	y = 15 + StepH
    ResizeGadget(#strPath, #PB_Ignore, y, w - w / 15 - 18, StepH)
    ResizeGadget(#btnOpen, w - w / 15 - 8, y - 1, w / 15, StepH + 2)
	y = (11 + StepH) * 2 + 1
    ResizeGadget(#chNewFile, #PB_Ignore, y, w / 3, StepH)
    ResizeGadget(#StatusBar, w / 3 + 40, y, w / 3 * 2 - 50, StepH + 2)
    y = (11 + StepH) * 3
    StepH + 2
    ResizeGadget(#cmbx6, #PB_Ignore, y, w / 3 + 20, StepH)
    ResizeGadget(#btnEncoder, w / 3 + 40, y, w / 3 - 40, StepH)
    ResizeGadget(#btnDecoder, w / 3 * 2 + 10, y, w / 3 - 20, StepH)
EndProcedure
User avatar
minimy
Enthusiast
Enthusiast
Posts: 610
Joined: Mon Jul 08, 2013 8:43 pm
Location: off world

Re: Encode / Decode (GUI)

Post by minimy »

Hey, here work perfect. Very nice job. Thanks for share!

this is the translation to spanish. :mrgreen:

Code: Select all

ElseIf UserIntLang = 3082 ; es
	Lng(0) = "Codificar / Decodificar"
	Lng(1) = "Archivo nuevo"
	Lng(2) = "Introduce tu clave"
	Lng(3) = "Pon la ruta del archivo o arrástralo hasta aquí"
	Lng(4) = "Manual"
	Lng(5) = "Auto codifica"
	Lng(6) = "Auto decodifica"
	Lng(7) = "Codificar"
	Lng(8) = "Decodificar"
	Lng(9) = "Mensaje"
	Lng(10) = "La ruta de disco no existe"
	Lng(11) = "Sin clave"
	Lng(12) = "Hecho, error="
If translation=Error: reply="Sorry, Im Spanish": Endif
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Encode / Decode (GUI)

Post by Kwai chang caine »

Can be usefull, thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply