Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- need to optimise all this
- local blocksize = 5
- local bit32 = 2 ^ 32
- local prime1 = 8747
- local prime2 = 2147483647
- local bit32half = bit32/2
- local floor = math.floor
- local function keygen( seed, length )
- local count = 1
- local keys, garbage = {}, {}
- for i = 1, length, blocksize do
- seed = ( seed * ( seed > bit32half and prime2 or prime1 ) + 1 ) % bit32 + count
- count = count + 1
- garbage[i] = math.max( 0, ( seed - 1 ) % 10 - 4 )
- keys[i] = seed % 256
- end
- return keys, garbage
- end
- local h = {}
- for i = 0, 15 do
- h[i] = ("%X"):format( i )
- end
- local hl = {}
- for i = 0, 15 do
- hl[("%X"):format( i )] = i
- end
- local function tohex2( n )
- return h[math.floor( n / 16 )] .. h[n % 16]
- end
- local function fromhex2( h )
- return hl[h:sub( 1, 1 )] * 16 + hl[h:sub( 2, 2 )]
- end
- local function numbertochars( n )
- local s = tohex2( n % 256 )
- for i = 1, 3 do
- n = math.floor( n / 256 )
- s = tohex2( n % 256 ) .. s
- end
- return s
- end
- local function charstonumber( c )
- local n = 0
- for i = 1, 4 do
- n = n * 256 + fromhex2( c:sub( i * 2 - 1 ) )
- end
- return n
- end
- local function newgarbage( length )
- if length == 0 then return "" end
- return tohex2( math.random( 0, 255 ) ) .. newgarbage( length - 1 )
- end
- local function stringkey( str )
- local key = 0
- for i = 1, #str do
- key = key * 256 + str:byte( i )
- end
- return key
- end
- local encrypt = {}
- function encrypt.encrypt( text, key )
- key = type( key ) == "string" and stringkey( key ) or key
- text = textutils.serialize( text )
- if type( key ) ~= "number" then
- return error( "expected number/string key, got " .. type( key ) )
- end
- local keys, garbage = keygen( key, #text )
- local cipher = { numbertochars( #text ) }
- math.randomseed( os.clock() )
- for i = 1, #text, blocksize do
- for n = 0, blocksize - 1 do
- if i + n <= #text then
- cipher[#cipher + 1] = tohex2( bit.bxor( text:byte( i + n ), keys[i] ) )
- else
- break
- end
- end
- cipher[#cipher + 1] = newgarbage( garbage[i] )
- end
- return table.concat( cipher )
- end
- function encrypt.decrypt( cipher, key )
- key = type( key ) == "string" and stringkey( key ) or key
- if type( cipher ) ~= "string" then
- return error( "expected string cipher, got " .. type( cipher ) )
- end
- if type( key ) ~= "number" then
- return error( "expected number/string key, got " .. type( key ) )
- end
- local length = charstonumber( cipher:sub( 1, 8 ) )
- cipher = cipher:sub( 9 )
- local keys, garbage = keygen( key, length )
- local text = {}
- local i = 1
- while #cipher > 0 do
- local block = cipher:sub( 1, math.min( #cipher - garbage[i] * 2, blocksize * 2 ) )
- for n = 1, #block, 2 do
- text[#text + 1] = string.char( bit.bxor( fromhex2( block:sub( n ) ), keys[i] ) )
- end
- cipher = cipher:sub( blocksize * 2 + garbage[i] * 2 + 1 )
- i = i + blocksize
- end
- return textutils.unserialize( table.concat( text ) )
- end
- return encrypt
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement