Skip to content

Instantly share code, notes, and snippets.

@Cheatoid
Created February 15, 2022 13:26
Show Gist options
  • Save Cheatoid/c6c35be390a69f7343bd8e40a2b66ea3 to your computer and use it in GitHub Desktop.
Save Cheatoid/c6c35be390a69f7343bd8e40a2b66ea3 to your computer and use it in GitHub Desktop.
Curated (table) Xor cipher benchmarks across LuaJIT, LuaJIT interpreter and Cobalt (ComputerCraft: Tweaked)
-- Note: do use local(ization) for better performance when JIT is off
local pairs, ipairs, next, rawset, rawget, bit_bxor = pairs, ipairs, next, rawset, rawget, bit32 and bit32.bxor or bit.bxor
local Xor0 = function(t, k)
-- assume `t` and `k` are (non empty) byte arrays (sequential & numeric indexed Lua tables)
local x = {}
for i = 1, #t do
x[i] = bit_bxor(t[i], k[((i - 1) % #k) + 1])
end
return x
end
local XorRaw0 = function(t, k)
local x = {}
for i = 1, #t do
rawset(x, i, bit_bxor(rawget(t, i), rawget(k, ((i - 1) % #k) + 1)))
end
return x
end
local XorInv0 = function(t, k)
local x = {}
for i = #t, 1, -1 do
x[i] = bit_bxor(t[i], k[((i - 1) % #k) + 1])
end
return x
end
local XorRawInv0 = function(t, k)
local x = {}
for i = #t, 1, -1 do
rawset(x, i, bit_bxor(rawget(t, i), rawget(k, ((i - 1) % #k) + 1)))
end
return x
end
-- self-modify variants:
local Xor1 = function(t, k)
for i = 1, #t do
t[i] = bit_bxor(t[i], k[((i - 1) % #k) + 1])
end
end
local XorRaw1 = function(t, k)
for i = 1, #t do
rawset(t, i, bit_bxor(rawget(t, i), rawget(k, ((i - 1) % #k) + 1)))
end
end
local XorInv1 = function(t, k)
for i = #t, 1, -1 do
t[i] = bit_bxor(t[i], k[((i - 1) % #k) + 1])
end
end
local XorRawInv1 = function(t, k)
for i = #t, 1, -1 do
rawset(t, i, bit_bxor(rawget(t, i), rawget(k, ((i - 1) % #k) + 1)))
end
end
local Xor2 = function(t, k)
local j = 1
for i = 1, #t do
t[i] = bit_bxor(t[i], k[j])
j = j + 1
if j > #k then
j = 1
end
end
end
local Xor3 = function(t, k)
local l, j = #k, 1
for i = 1, #t do
t[i] = bit_bxor(t[i], k[j])
j = j + 1
if j > l then
j = 1
end
end
end
local Xor4 = function(t, k)
for i, b in next, t do
t[i] = bit_bxor(b, k[((i - 1) % #k) + 1])
end
end
local Xor5 = function(t, k)
local j = 1
for i, b in next, t do
t[i] = bit_bxor(b, k[j])
j = j + 1
if j > #k then
j = 1
end
end
end
local Xor6 = function(t, k)
local l, j = #k, 1
for i, b in next, t do
t[i] = bit_bxor(b, k[j])
j = j + 1
if j > l then
j = 1
end
end
end
local Xor7 = function(t, k)
--assert(#k >= #t)
for i, b in next, t do
t[i] = bit_bxor(b, k[i])
end
end
local XorRaw7 = function(t, k)
for i, b in next, t do
rawset(t, i, bit_bxor(b, rawget(k, i)))
end
end
local XorPairs7 = function(t, k)
for i, b in pairs(t) do
t[i] = bit_bxor(b, k[i])
end
end
local XorIpairs7 = function(t, k)
for i, b in ipairs(t) do
t[i] = bit_bxor(b, k[i])
end
end
math.randomseed(1)
local SECRET, KEY = {}, {}
for i = 1, 8 do SECRET[i] = math.random(0, 0xFF) end
for i = 1, 8 do KEY[i] = math.random(0, 0xFF) end -- for optimal performance & security, make sure to satisfy: #KEY >= #SECRET
local TIME = jit and os.clock() or (os.epoch 'utc' / 1000) -- normalize time between our environments
-- shorter is better; best times are starred with **; all times are measured in seconds
-- average execution time :(JIT on) | (JIT off) | (CC:T)
for _ = 1, 1000000 do --sterr: 0.0005| 0.006 | 0.038
--Xor0(SECRET, KEY) -- 0.635 | 0.903 | 5.0801 - 5.1428
--XorRaw0(SECRET, KEY) -- 0.63 | 1.345 | too long
--XorInv0(SECRET, KEY) -- 0.525 | 0.852 | 5.7576 - 5.7826
--XorRawInv0(SECRET, KEY) -- 0.52 | 1.21 | too long
--- self-modify variants ---
--Xor1(SECRET, KEY) -- 0.111 | 0.474 | 4.1328
--XorRaw1(SECRET, KEY) -- 0.111 | 0.867 | too long
--XorInv1(SECRET, KEY) -- 0.112 | 0.477 | 4.1224
--XorRawInv1(SECRET, KEY) -- 0.111 | 0.873 | too long
--Xor2(SECRET, KEY) -- 0.065 | 0.39 | 3.7272
--Xor3(SECRET, KEY) -- **0.065 | 0.316 | 3.3189 ; fastest with JIT on
--Xor4(SECRET, KEY) -- 0.157 | 0.468 | 4.8955
--Xor5(SECRET, KEY) -- 0.108 | 0.362 | 4.4412
--Xor6(SECRET, KEY) -- 0.112 | 0.3 | 3.9734
--Xor7(SECRET, KEY) -- 0.09 | 0.245** | 3.3026** ; fastest with JIT off (aka with [JIT] interpreter) & Cobalt
--XorRaw7(SECRET, KEY) -- 0.09 | 0.602 | 6.1845
--XorPairs7(SECRET, KEY) -- 0.09 | 0.255 | 3.3987
--XorIpairs7(SECRET, KEY) -- 0.057 | 0.332 | 3.3995
end
print((jit and os.clock() or (os.epoch 'utc' / 1000)) - TIME)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment