Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- modEM
- A custom peripheral API wrapper.
- This API is specifically made to create secure connections between two computers.
- How it works:
- You specify a channel for the connection, the 2nd computer connects to it.
- Ones the API recognizes a 2nd connection, it generates a random number (between 1 and 65535) and passes it to the 2nd computer.
- It then generates a random string, containing symbols and numbers, and passes that to the 2nd computer too.
- The API then closes the channel and opens a new one using the new generated number.
- The 2nd computer connects to that using the number the API gave him.
- Now why is that all necessary?
- It passes a random number and opens a new channel on that to prevent from a 3rd party being able to listen on it.
- Sure he can guess the number but it'd need a while.
- It also passes a random string to the 2nd computer, because it ENCRYPTS the messages using that string.
- Which leads to a higher security if a 3rd party is listening on that channel too.
- This is mainly made for future secret projects :)
- ~Piorjade 2016
- ]]
- --[[
- THIS IS THE ENCRYPTION API MADE BY "PixelToast"
- ]]
- local function zfill(N)
- N=string.format("%X",N)
- Zs=""
- if #N==1 then
- Zs="0"
- end
- return Zs..N
- end
- local function serializeImpl(t)
- local sType = type(t)
- if sType == "table" then
- local lstcnt=0
- for k,v in pairs(t) do
- lstcnt = lstcnt + 1
- end
- local result = "{"
- local aset=1
- for k,v in pairs(t) do
- if k==aset then
- result = result..serializeImpl(v)..","
- aset=aset+1
- else
- result = result..("["..serializeImpl(k).."]="..serializeImpl(v)..",")
- end
- end
- result = result.."}"
- return result
- elseif sType == "string" then
- return string.format("%q",t)
- elseif sType == "number" or sType == "boolean" or sType == "nil" then
- return tostring(t)
- elseif sType == "function" then
- local status,data=pcall(string.dump,t)
- if status then
- return 'func('..string.format("%q",data)..')'
- else
- error()
- end
- else
- error()
- end
- end
- local function split(T,func)
- if func then
- T=func(T)
- end
- local Out={}
- if type(T)=="table" then
- for k,v in pairs(T) do
- Out[split(k)]=split(v)
- end
- else
- Out=T
- end
- return Out
- end
- local function serialize( t )
- t=split(t)
- return serializeImpl( t, tTracking )
- end
- local function unserialize( s )
- local func, e = loadstring( "return "..s, "serialize" )
- local funcs={}
- if not func then
- return e
- end
- setfenv( func, {
- func=function(S)
- local new={}
- funcs[new]=S
- return new
- end,
- })
- return split(func(),function(val)
- if funcs[val] then
- return loadstring(funcs[val])
- else
- return val
- end
- end)
- end
- local function sure(N,n)
- if (l2-n)<1 then N="0" end
- return N
- end
- local function splitnum(S)
- Out=""
- for l1=1,#S,2 do
- l2=(#S-l1)+1
- CNum=tonumber("0x"..sure(string.sub(S,l2-1,l2-1),1) .. sure(string.sub(S,l2,l2),0))
- Out=string.char(CNum)..Out
- end
- return Out
- end
- local function wrap(N)
- return N-(math.floor(N/256)*256)
- end
- local function checksum(S,num)
- local sum=0
- for char in string.gmatch(S,".") do
- for l1=1,(num or 1) do
- math.randomseed(string.byte(char)+sum)
- sum=sum+math.random(0,9999)
- end
- end
- math.randomseed(sum)
- return sum
- end
- local function genkey(len,psw)
- checksum(psw)
- local key={}
- local tKeys={}
- for l1=1,len do
- local num=math.random(1,len)
- while tKeys[num] do
- num=math.random(1,len)
- end
- tKeys[num]=true
- key[l1]={num,math.random(0,255)}
- end
- return key
- end
- local function encrypt(data,psw)
- data=serialize(data)
- local chs=checksum(data)
- local key=genkey(#data,psw)
- local out={}
- local cnt=1
- for char in string.gmatch(data,".") do
- table.insert(out,key[cnt][1],zfill(wrap(string.byte(char)+key[cnt][2])),chars)
- cnt=cnt+1
- end
- return string.sub(serialize({chs,table.concat(out)}),2,-3)
- end
- local function decrypt(data,psw)
- local oData=data
- data=unserialize("{"..data.."}")
- if type(data)~="table" then
- return oData
- end
- local chs=data[1]
- data=data[2]
- local key=genkey((#data)/2,psw)
- local sKey={}
- for k,v in pairs(key) do
- sKey[v[1]]={k,v[2]}
- end
- local str=splitnum(data)
- local cnt=1
- local out={}
- for char in string.gmatch(str,".") do
- table.insert(out,sKey[cnt][1],string.char(wrap(string.byte(char)-sKey[cnt][2])))
- cnt=cnt+1
- end
- out=table.concat(out)
- if checksum(out or "")==chs then
- return unserialize(out)
- end
- return oData,out,chs
- end
- --[[
- ENCRYPTION API ENDS HERE
- ]]
- local chan = 0
- local encryption = "abc"
- local isConnected = false
- local function makeString(l)
- if l < 1 then return nil end -- Check for l < 1
- local s = "" -- Start string
- for i = 1, l do
- n = math.random(32, 126) -- Generate random number from 32 to 126
- if n == 96 then n = math.random(32, 95) end
- s = s .. string.char(n) -- turn it into character and add to string
- end
- return s -- Return string
- end
- function open(side)
- if modem then
- return false, "modemWrapped"
- end
- modem = peripheral.wrap(side)
- end
- function close()
- modem.closeAll()
- isConnected = false
- chan = 0
- encryption = "abc"
- modem = nil
- end
- function host(startingChannel, side, timout)
- if modem then
- return false, "modemWrapped"
- end
- if type(timeout) == "number" then
- local timerID = os.startTimer(timeout)
- end
- if startingChannel == nil or startingChannel < 1 or startingChannel > 65535 then
- startingChannel = os.getComputerID()
- end
- chan = startingChannel
- if type(side) ~= "string" then return false end
- open(side)
- modem.open(chan)
- while true do
- local ev, a, b, c, msg, dis = os.pullEvent()
- if ev == "modem_message" and msg == "Connected." then
- local tab = {
- msg = "ok",
- newPort = 1,
- decPass = "abc",
- }
- tab.newPort = math.random(1, 65535)
- tab.decPass = makeString(6)
- encryption = tab.decPass
- modem.transmit(chan, chan, textutils.serialize(tab))
- modem.close(chan)
- chan = tab.newPort
- modem.open(chan)
- isConnected = true
- break
- elseif ev == "timer" and a == timerID then
- close()
- return false, "timeout"
- end
- end
- end
- function connect(startingChannel, timeout)
- if modem == nil then return false, "No opened modem." end
- if type(timeout) == "number" then
- local timerID = os.startTimer(timeout)
- end
- chan = startingChannel
- modem.closeAll()
- modem.open(chan)
- modem.transmit(chan, chan, "Connected.")
- while true do
- ev, side, sendChan, repChan, msg, distance = os.pullEvent()
- if ev == "modem_message" then
- msg = textutils.unserialize(msg)
- if msg.msg == "ok" then
- modem.closeAll()
- chan = msg.newPort
- modem.open(chan)
- encryption = msg.decPass
- break
- end
- elseif ev == "timer" and side == timerID then
- close()
- return false, "timeout"
- end
- end
- isConnected = true
- end
- function receive(timeout)
- if not isConnected then
- return false, "noConnection"
- end
- if not modem then return false, "No opened modem." end
- if type(timeout) == "number" then
- local timerID = os.startTimer(timout)
- end
- while true do
- local ev, a, b, c, msg, dis = os.pullEvent()
- if ev == "timer" and a == timerID then
- return false, "timeout"
- elseif ev == "modem_message" and msg ~= nil then
- return decrypt(msg, encryption)
- end
- end
- end
- function send(msg)
- if not isConnected then
- return false, "noConnection"
- end
- if not modem then return false, "No opened modem." end
- modem.transmit(chan, chan, encrypt(msg, encryption))
- return
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement