parent
928ec9dace
commit
6b185ba155
|
@ -0,0 +1,44 @@
|
|||
-- HOW TO DOWNLOAD WEBPAGES/FILES USING ROBOT
|
||||
|
||||
if not fetch then
|
||||
fetch = _G.basic_robot.http_api.fetch;
|
||||
|
||||
-- WARNING: this is run outside pcall and can crash server if errors!
|
||||
result = function(res) -- res.data is string containing result
|
||||
if not res.succeeded then self.label("#ERROR: data couldn't be downloaded :\n" .. minetest.serialize(res) ) return end
|
||||
if res.data then self.label(res.data) end
|
||||
end
|
||||
|
||||
fetch({url = "http://185.85.149.248/FILES/minetest/README.txt", timeout = 30}, result)
|
||||
end
|
||||
|
||||
--[[
|
||||
from https://github.com/minetest/minetest/blob/master/doc/lua_api.txt :
|
||||
|
||||
`HTTPRequest` definition
|
||||
------------------------
|
||||
|
||||
Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`.
|
||||
|
||||
{
|
||||
url = "http://example.org",
|
||||
timeout = 10,
|
||||
-- ^ Timeout for connection in seconds. Default is 3 seconds.
|
||||
post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"},
|
||||
-- ^ Optional, if specified a POST request with post_data is performed.
|
||||
-- ^ Accepts both a string and a table. If a table is specified, encodes
|
||||
-- ^ table as x-www-form-urlencoded key-value pairs.
|
||||
-- ^ If post_data ist not specified, a GET request is performed instead.
|
||||
user_agent = "ExampleUserAgent",
|
||||
-- ^ Optional, if specified replaces the default minetest user agent with
|
||||
-- ^ given string.
|
||||
extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" },
|
||||
-- ^ Optional, if specified adds additional headers to the HTTP request.
|
||||
-- ^ You must make sure that the header strings follow HTTP specification
|
||||
-- ^ ("Key: Value").
|
||||
multipart = boolean
|
||||
-- ^ Optional, if true performs a multipart HTTP request.
|
||||
-- ^ Default is false.
|
||||
}
|
||||
|
||||
--]]
|
|
@ -0,0 +1,207 @@
|
|||
--ENIGMA emulator by rnd
|
||||
-- programming ~30 mins, total 3hrs 30 minutes with debugging - cause of youtube video with missing
|
||||
-- key detail - reflector!
|
||||
|
||||
-- REFERENCES:
|
||||
-- 1. https://en.wikipedia.org/wiki/Enigma_machine
|
||||
-- 2. http://users.telenet.be/d.rijmenants/en/enigmatech.htm#reflector
|
||||
-- 3. https://www.youtube.com/watch?src_vid=V4V2bpZlqx8&v=G2_Q9FoD-oQ
|
||||
|
||||
-- default settings
|
||||
settings = {}
|
||||
settings.set = function(reflector, plugboard, rotors)
|
||||
settings.reflector = reflector or 2017
|
||||
settings.plugboard = plugboard or 2017
|
||||
settings.rotors = {}
|
||||
if rotors then
|
||||
table.insert(settings.rotors, rotors[1])
|
||||
table.insert(settings.rotors, rotors[2])
|
||||
table.insert(settings.rotors, rotors[3])
|
||||
table.insert(settings.rotors, rotors[4])
|
||||
else
|
||||
table.insert(settings.rotors, 0)
|
||||
table.insert(settings.rotors, 0)
|
||||
table.insert(settings.rotors, 0)
|
||||
table.insert(settings.rotors, 2018)
|
||||
table.insert(settings.rotors, 2017)
|
||||
table.insert(settings.rotors, 2020)
|
||||
end
|
||||
--if not enigma_encrypt then
|
||||
if true then
|
||||
scramble = function(input,password,sgn) -- permutes text randomly, nice after touch to stream cypher to prevent block analysis
|
||||
_G.math.randomseed(password);
|
||||
local n = #input;
|
||||
local permute = {}
|
||||
for i = 1, n do permute[i] = i end --input:sub(i, i)
|
||||
for i = n,2,-1 do
|
||||
local j = math.random(i-1);
|
||||
local tmp = permute[j];
|
||||
permute[j] = permute[i]; permute[i] = tmp;
|
||||
end
|
||||
local out = {};
|
||||
if sgn>0 then -- unscramble
|
||||
for i = 1,n do out[permute[i]] = string.sub(input,i,i) end
|
||||
else -- scramble
|
||||
for i = 1,n do out[i] = string.sub(input,permute[i],permute[i]) end
|
||||
end
|
||||
return table.concat(out,"")
|
||||
end
|
||||
|
||||
local permutation = function(n,password,sgn) -- create random permutation of numbers 1,...,n
|
||||
_G.math.randomseed(password);
|
||||
local permute = {}
|
||||
for i = 1, n do permute[i] = i end
|
||||
for i = n,2,-1 do
|
||||
local j = math.random(i-1);
|
||||
local tmp = permute[j];
|
||||
permute[j] = permute[i]; permute[i] = tmp;
|
||||
end
|
||||
return permute;
|
||||
end
|
||||
|
||||
-- produces permutation U such that U^2 = 1; modified fisher-yates shuffle by rnd
|
||||
local reflector = function(n,password)
|
||||
_G.math.randomseed(password)
|
||||
local permute = {}
|
||||
local used = {};
|
||||
for i = 1, n do permute[i] = i end
|
||||
local rem = n;
|
||||
|
||||
for i = n,2,-1 do
|
||||
if not used[i] then
|
||||
local j = math.random(rem);
|
||||
-- now we need to find j-th unused idx
|
||||
local k = 1; local l = 0; -- k position, l how many we tried
|
||||
while l < j do
|
||||
if not used[k] then l=l+1; end
|
||||
k=k+1
|
||||
end
|
||||
j=k-1;
|
||||
|
||||
used[i]=true; used[j] = true;
|
||||
local tmp = permute[j];
|
||||
permute[j] = permute[i]; permute[i] = tmp;
|
||||
rem = rem - 2;
|
||||
end
|
||||
|
||||
end
|
||||
return permute;
|
||||
end
|
||||
|
||||
|
||||
local inverse_table = function(tbl)
|
||||
local ret = {};
|
||||
for i = 1,#tbl do
|
||||
ret[ tbl[i] ] = i;
|
||||
end
|
||||
return ret;
|
||||
end
|
||||
|
||||
local rotors = {}; -- { permutation, work index }}
|
||||
local invrotors = {}; -- reversed tables
|
||||
|
||||
-- SETUP REFLECTOR, ROTORS AND PLUGBOARD!
|
||||
local enigma_charcount = 127-32+1; -- n = 96
|
||||
local enigma_charstart = 32;
|
||||
local reflector = reflector(enigma_charcount,settings.reflector); -- this is permutation U such that U^2 = id --
|
||||
|
||||
local plugboard = permutation(enigma_charcount,settings.plugboard,1); -- setup plugboard for enigma machine
|
||||
local invplugboard = inverse_table(plugboard);
|
||||
|
||||
for i = 1,3 do rotors[i] = {rotor = permutation(enigma_charcount,settings.rotors[3 + i],1), idx = 0} end -- set up 3 rotors together with their indices
|
||||
for i = 1,3 do invrotors[i] = {rotor = inverse_table(rotors[i].rotor)} end -- set up 3 rotors together with their indices
|
||||
|
||||
-- how many possible setups:
|
||||
--[[
|
||||
n = charcount;
|
||||
rotors positions: n^3
|
||||
plugboard wiring : n!
|
||||
reflector wiring: n! / (2^n * (n/2)!)
|
||||
TOTAL: (n!)^2*n^3 / ( 2^n * (n/2)! ) ~ 6.4 * 10^77
|
||||
rotor positions & plugboard wiring: (n!)*n^3 ~ 4.8 * 10^57 (n=43)
|
||||
--]]
|
||||
|
||||
-- END OF SETUP
|
||||
|
||||
local rotate_rotor = function(i)
|
||||
local carry = 1;
|
||||
for j = i,1,-1 do
|
||||
local idx = rotors[j].idx;
|
||||
idx = idx + 1;
|
||||
if idx>=enigma_charcount then
|
||||
carry = 1;
|
||||
else
|
||||
carry = 0;
|
||||
end
|
||||
rotors[j].idx = idx % enigma_charcount;
|
||||
if carry == 0 then break end
|
||||
end
|
||||
end
|
||||
|
||||
local enigma_encrypt_char = function(x) -- x : 1 .. enigma_charcount
|
||||
-- E = P.R1.R2.R3.U.R3^-1.R2^-1.R1^-1.P^-1, P = plugboard, R = rotor, U = reflector
|
||||
x = plugboard[x];
|
||||
for i = 1,3 do
|
||||
local idx = rotors[i].idx;
|
||||
x = rotors[i].rotor[((x+idx-1) % enigma_charcount)+1];
|
||||
end
|
||||
|
||||
x = reflector[x];
|
||||
|
||||
for i = 3,1,-1 do
|
||||
local idx = rotors[i].idx;
|
||||
x = invrotors[i].rotor[x];
|
||||
x = ((x-1-idx) % enigma_charcount)+1
|
||||
|
||||
end
|
||||
|
||||
x = invplugboard[x];
|
||||
-- apply rotation to rotor - and subsequent rotors if necessary
|
||||
rotate_rotor(3)
|
||||
return x;
|
||||
end
|
||||
|
||||
|
||||
--enigma_encrypt = function(input)
|
||||
settings.encrypt = function(input)
|
||||
-- rotor settings!
|
||||
rotors[1].idx = settings.rotors[1]
|
||||
rotors[2].idx = settings.rotors[2]
|
||||
rotors[3].idx = settings.rotors[3]
|
||||
|
||||
local ret = "";
|
||||
for i = 1,#input do
|
||||
local c = string.byte(input,i) - enigma_charstart +1;
|
||||
--say(i .. " : " .. c)
|
||||
if c>=1 and c<=enigma_charcount then
|
||||
c = enigma_encrypt_char(c);
|
||||
end
|
||||
ret = ret .. string.char(enigma_charstart+c-1);
|
||||
end
|
||||
return ret
|
||||
|
||||
end
|
||||
settings.decrypt = settings.encrypt
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
msg = self.listen_msg()
|
||||
if msg then
|
||||
msg = minetest.strip_colors(msg)
|
||||
local mark = string.find(msg,"@e") -- delimiter in chat
|
||||
if mark then
|
||||
msg = string.sub(msg,mark+2);
|
||||
msg = minetest.colorize("yellow",enigma_encrypt(msg))
|
||||
say(minetest.colorize("red","#decrypted : ") .. msg)
|
||||
end
|
||||
end
|
||||
|
||||
msg = self.sent_msg()
|
||||
if msg then
|
||||
local msg = enigma_encrypt(msg);
|
||||
say("@e" .. msg,true)
|
||||
-- minetest.show_formspec("encrypted_text", "size[4,4] textarea[0,-0.25;5,5;text;;".. "@e" .. minetest.formspec_escape(msg) .. "]")
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue