local function sum( n, ... )
local t = { ... }
for i = 1, #t do
n = n + t[i]
end
return n
end
local function loop( n, lim )
while n > lim do
n = n - lim
end
while n < 1 do
n = n + lim
end
return n
end
local function shift( str, count )
local str = { str:byte( 1, #str ) }
for i = 1, #str do
str[i] = loop( str[i] + count, 255 )
end
for i = 1, #str do
str[i] = string.char( str[i] )
end
return table.concat( str, "" )
end
local function tohex( b )
local n = 0
for i = 1, 4 do
n = n * 2
n = n + tonumber( b:sub( i, i ) )
end
if n >= 10 then
local hexes = { "A", "B", "C", "D", "E", "F" }
return hexes[n - 9]
end
return tostring( n )
end
local function fromhex( h )
local n = tonumber( h )
if not n then
local hexes = { ["A"] = 10, ["B"] = 11, ["C"] = 12, ["D"] = 13, ["E"] = 14, ["F"] = 15 }
n = hexes[h]
end
local str = ""
for i = 1, 4 do
str = str .. n % 2
n = math.floor( n / 2 )
end
return str:reverse( )
end
local function xor( n1, n2 )
if n1 > 255 or n2 > 255 or n1 < 0 or n2 < 0 then
return error "expected numbers between 0 and 255"
end
local bit1, bit2 = { }, { }
for i = 1, 8 do
bit1[9-i] = n1 % 2 == 1
n1 = math.floor( n1 / 2 )
end
for i = 1, 8 do
bit2[9-i] = n2 % 2 == 1
n2 = math.floor( n2 / 2 )
end
local bits = { }
for i = 1, 8 do
bits[i] = ( bit1[i] and not bit2[i] ) or ( not bit1[i] and bit2[i] )
end
local n = 0
for i = 1, 8 do
n = n * 2
n = n + ( bits[i] and 1 or 0 )
end
return n
end
local function nand( n1, n2 )
if n1 > 255 or n2 > 255 or n1 < 0 or n2 < 0 then
return error "expected numbers between 0 and 255"
end
local bit1, bit2 = { }, { }
for i = 1, 8 do
bit1[9-i] = n1 % 2 == 1
n1 = math.floor( n1 / 2 )
end
for i = 1, 8 do
bit2[9-i] = n2 % 2 == 1
n2 = math.floor( n2 / 2 )
end
local bits = { }
for i = 1, 8 do
bits[i] = not bit1[i] == bit2[i]
end
local n = 0
for i = 1, 8 do
n = n * 2
n = n + ( bits[i] and 1 or 0 )
end
return n
end
local function tobits( n )
local str = ""
for i = 1, 8 do
str = str .. n % 2
n = math.floor( n / 2 )
end
return str:reverse( )
end
local function frombits( b )
local n = 0
for i = 1, 8 do
n = n * 2
n = n + tonumber( b:sub( i, i ) )
end
return n
end
local t = os.clock( )
local function start( )
t = os.clock( )
end
local function yield( )
if os.clock( ) - t > .1 then -- change the yield timeout here, by default, it yields every .1 seconds
coroutine.yield( )
start( )
end
end
function encrypt( str, key ) -- string text, string key
local enc = ""
start( )
for i = 1, #str do
math.randomseed( sum( key:byte( 1, #key ) ) )
key = shift( key, math.random( 1, 100 ) )
local ki = loop( i, #key )
local a = str:sub( i, i ):byte( )
local b = key:sub( ki, ki ):byte( )
enc = enc .. tobits( xor( a, b ) )
yield( )
end
local enc2 = ""
for i = 1, #enc / 4 do
enc2 = enc2 .. tohex( enc:sub( i * 4 - 3, i * 4 ) )
yield( )
end
return enc2
-- string cipher
end
function decrypt( str, key ) -- string cipher, string key
start( )
local dec2 = ""
for i = 1, #str do
dec2 = dec2 .. fromhex( str:sub( i, i ) )
yield( )
end
str = dec2
local dec = ""
local keys = { }
for i = 1, #str / 8 do
math.randomseed( sum( key:byte( 1, #key ) ) )
keys[i] = shift( key, math.random( 1, 100 ) )
key = keys[i]
yield( )
end
for i = 1, #str / 8 do
local ki = loop( i, #key )
local a = frombits( str:sub( ( i - 1 ) * 8 + 1, i * 8 ) )
local b = string.byte( keys[i]:sub( ki, ki ) )
dec = dec .. string.char( nand( a, b ) )
yield( )
end
return dec
-- string text
end