Thanks for explaining guys. I think my workaround is OK. This is what I did with it:
Code: Select all
#notrayicon
#noenv
#singleinstance, ignore
setbatchlines, -1
setworkingdir, %a_scriptdir%
base := _random(-2147483648, 2147483647)
menu, tray, nostandard
menu, tray, tip, XOR+
menu, tray, add, Restore, win
menu, tray, add, About, about
menu, tray, add
menu, tray, add, Exit, guiclose
menu, tray, default, restore
menu, text, add, Load from file..., openfile
menu, text, add
menu, text, add, Save to file..., savetofile
menu, text, add, Save to clipboard, savetoclip
menu, text, icon, Load from file..., SHELL32.dll, 71, 16
menu, text, icon, Save to file..., SHELL32.dll, 71, 16
menu, text, icon, Save to clipboard, SHELL32.dll, 22, 16
menu, mainbar, add, File, :text
menu, mainbar, add, About, about
gui, menu, mainbar
gui, font, s8
gui, +resize +minsize
gui, add, groupbox, x10 y0 w350 h226 vgbxmain
gui, add, edit, vscroll wanttab x20 y16 w330 h170 vtext,
gui, add, edit, x20 y196 w200 h20 vpass,
gui, add, button, x230 y196 w60 h20 vbtnencipher gencipher, Encipher
gui, add, button, x290 y196 w60 h20 vbtndecipher gdecipher, Decipher
gui, show, w370 h236, XOR+
return
savetoclip:
{
gui, submit, nohide
gui, +owndialogs
if (text = "")
{
msgbox, 64, Save..., The text field is empty., 10
}
else
{
clipboard := text
msgbox, 64, Save..., Your text has been saved to the clipboard., 10
}
}
return
savetofile:
{
gui, submit, nohide
gui, +owndialogs
if (text = "")
{
msgbox, 64, Save..., The text field is empty., 10
}
else
{
fileselectfile, path, s18, *.txt, Save to file..., (*.txt)
if (path != "")
{
if fileexist(path)
{
filedelete, %path%
}
fileappend, %text%, %path%, utf-8
splitpath, path, name
msgbox, 64, Save..., Your text has been saved to "%name%"., 10
}
}
}
return
openfile:
{
gui, +owndialogs
fileselectfile, path, 3, *.txt, Open file..., (*.txt)
fileread, content, %path%
stringreplace, content, content, `r`n, `n, 1
guicontrol, , text, %content%
}
return
encipher:
{
gui, submit, nohide
gui, +owndialogs
if (text = "") && (pass = "")
{
msgbox, 64, Encipher..., Both fields are empty., 10
}
else if (text = "")
{
msgbox, 64, Encipher..., The text field is empty., 10
}
else if (pass = "")
{
msgbox, 64, Encipher..., The password field is empty., 10
}
else
{
stringreplace, text, text, `r`n, `n, 1
ciphertext := _encipher(text, pass)
guicontrol, , text, %ciphertext%
}
}
return
decipher:
{
gui, submit, nohide
gui, +owndialogs
if (text = "") && (pass = "")
{
msgbox, 64, Decipher..., Both fields are empty., 10
}
else if (text = "")
{
msgbox, 64, Decipher..., The text field is empty., 10
}
else if (pass = "")
{
msgbox, 64, Decipher..., The password field is empty., 10
}
else
{
stringreplace, text, text, `r`n, `n, 1
plaintext := _decipher(text, pass)
guicontrol, , text, %plaintext%
}
}
return
_encipher(text, password)
{
key := _keygen(text, password)
loop, parse, text
{
out .= substr("000" . asc(a_loopfield) ^ asc(substr(key, mod(a_index, strlen(key)), 1)), -3)
}
return _convert(_scramble(out, password), password)
}
_decipher(text, password)
{
count := 1
key := _keygen(text, password)
text := _descramble(_restore(text, password), password)
loop, % strlen(text) / 4
{
chr := ltrim(substr(text, count, 4), 0)
out .= chr((chr ? chr : 0) ^ asc(substr(key, mod(a_index, strlen(key)), 1)))
count+=4
}
return out
}
_convert(input, seed)
{
global base
table := _scramble(_table(), seed)
min := "1|29|37|45|53|61|69|77|85|93"
max := "28|36|44|52|60|68|76|84|92|100"
stringsplit, table, table
stringsplit, min, min, |
stringsplit, max, max, |
loop, 10
{
x := a_index - 1
min_%x% := min%a_index%
max_%x% := max%a_index%
}
random, , base + 2147483648
loop parse, input
{
pick := _random(min_%a_loopfield%, max_%a_loopfield%)
output .= table%pick%
}
return output
}
_restore(input, seed)
{
table := _scramble(_table(), seed)
min := "1|29|37|45|53|61|69|77|85|93"
max := "28|36|44|52|60|68|76|84|92|100"
stringsplit, table, table
stringsplit, min, min, |
stringsplit, max, max, |
loop, 10
{
x := a_index - 1
min_%x% := min%a_index%
max_%x% := max%a_index%
}
loop, 10
{
index := a_index - 1
count := min_%index% - 1
while (count++ < max_%index%)
{
alpha := asc(table%count%)
num%alpha% := index
}
}
loop parse, input
{
char := asc(a_loopfield)
output .= num%char%
}
return output
}
_scramble(string, seed)
{
random, , seed
length := strlen(string)
loop, % length
{
random, position, 1, (length - a_index + 1)
out .= substr(string, position, 1)
string := substr(string, 1, position - 1) . substr(string, position + 1)
}
return out
}
_descramble(string, seed)
{
random, , seed
length := strlen(string)
loop, % length
{
random, position, 1, (length - a_index + 1)
char%a_index% := position
}
loop, % length
{
newstring := substr(newstring, 1, char%length% - 1) . substr(string, length, 1) . substr(newstring, char%length%)
length--
}
return newstring
}
_keygen(text, password)
{
seed := _hash(password)
random, , seed
loop, % strlen(text)
{
random, ran, 1, 1000
key .= chr(ran)
}
return key
}
_table()
{
loop, 100
{
out .= _chr(a_index - 1)
}
return out
}
_hash(string)
{
hash := 2166136261
loop, parse, string
{
hash := 16777619 * (hash ^ Asc(SubStr(string, A_Index, 1)))
}
return hash & 0xFFFFFFFF
}
_asc(input)
{
return input = "`n" ? 0 : input = "’" ? 96 : input = "–" ? 97 : input = "“" ? 98 : input = "”" ? 99 : asc(input) - asc(a_space) + 1
}
_chr(input)
{
return input = 0 ? "`n" : input = 96 ? "’" : input = 97 ? "–" : input = 98 ? "“" : input = 99 ? "”" : chr(input + asc(a_space) - 1)
}
about:
{
if (about_gui != 1)
{
gosub, get_about
gui, font, s8
gui, 2:add, button, x340 y275 w60 h20 ghome_site, Home
gui, 2:add, button, default x400 y275 w60 h20 g2guiclose, OK
gui, 2:add, edit, +readonly vscroll x10 y10 w450 h260, %about%
gui, 2:show, center w470 h300, About XOR+
about_gui := 1
}
else
{
gui, 2:destroy
about_gui := 0
}
}
return
get_about:
{
about :=
(
"Yet to be written..."
)
}
return
home_site:
{
;run, http://crzyinc.weebly.com/XOR+.html
msgbox, Home site not yet established...
}
return
guisize:
{
gui, +owndialogs
if (a_eventinfo = 1) && (flag != 1)
{
if (!set)
{
gui, restore
msgbox, 35, Minimize..., Send window to the system tray?
}
flag := 1
ifmsgbox yes
{
set := 1
}
ifmsgbox no
{
set := 2
}
if (set = 1)
{
gosub, win
}
else if (set = 2)
{
gui, minimize
}
}
else
{
anchor("gbxmain", "w h", 1)
anchor("text", "w h", 1)
anchor("pass", "y w", 1)
anchor("btnencipher", "x y", 1)
anchor("btndecipher", "x y", 1)
}
sleep, 200
flag := 0
}
return
win:
{
toggle := !toggle
if (toggle)
{
gui hide
menu, tray, icon
}
else
{
gui, show, center
menu, tray, noicon
}
}
return
guiclose:
{
gui, show
gui, submit, nohide
gui, +owndialogs
if (text != "") && (pass != "")
{
msgbox, 65, Close..., Text and password will be lost on exit.
}
else if (text != "")
{
msgbox, 65, Close..., Text will be lost on exit.
}
else if (pass != "")
{
msgbox, 65, Close..., Password will be lost on exit.
}
ifmsgbox cancel
{
return
}
exitapp
}
return
2guiclose:
{
gui, 2:destroy
about_gui := 0
}
return
_random(min, max)
{
random, var, %min%, %max%
return var
}
anchor(c, a = "", r = false)
{
static d
guicontrolget, p, pos, %c%
if ex := errorlevel
{
gui, %a_gui%:+lastfound
controlgetpos, px, py, pw, ph, %c%
}
if !(a_gui or px) and a
{
return
}
i = x.w.y.h./.7.%a_guiwidth%.%a_guiheight%.`n%a_gui%:%c%=
stringsplit, i, i, .
d := a ? d . ((n := !instr(d, i9)) ? i9 : "") : regexreplace(d, "\n\d+:" . c . "=[\-\.\d\/]+")
loop, 4
{
x := a_index, j := i%x%, i6 += x = 3
, k := !regexmatch(a, j . "([\d.]+)", v) + (v1 ? v1 : 0)
, e := p%j% - i%i6% * k, d .= n ? e . i5 : ""
, regexmatch(d, "\Q" . i9 . "\E(?:([\d.\-]+)/){" . x . "}", v)
, l .= p%j% := instr(a, j) ? (ex ? "" : j) . v1 + i%i6% * k : ""
}
if r
{
rx = draw
}
if ex
{
controlmove, %c%, px, py, pw, ph
}
else
{
guicontrol, move%rx%, %c%, %l%
}
}
This appears to work as intended. My only real concern is the _keygen() function. I have it set to generate random asc() characters between 1 and 1000. If I increase that number much beyond 1000 it begins to break the cipher. I believe having the key consist of the widest possible range of characters increases the security of the cipher, so is there a reason it messes up and/or a way to increase it without breaking it?