Advertisement
Alakazard12

robapi

Apr 14th, 2013
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 39.74 KB | None | 0 0
  1. function version()
  2.   return 1.12
  3. end
  4.  
  5. function explode(str, delimiter)
  6.     local result = { }
  7.     local from = 1
  8.     local delim_from, delim_to = string.find( str, delimiter, from )
  9.     while delim_from do
  10.         table.insert( result, string.sub( str, from , delim_from-1 ) )
  11.         from = delim_to + 1
  12.         delim_from, delim_to = string.find( str, delimiter, from )
  13.     end
  14.     table.insert( result, string.sub( str, from ) )
  15.     return result
  16. end
  17.  
  18. --[[
  19.  
  20.   Misc. utility functions
  21.  
  22. ]]
  23.  
  24. function randomOf(t)
  25.     return t[math.random(1, #t)];
  26. end
  27.  
  28. function applyToAll(fn, ...)
  29.     local inp = {...};
  30.     local out = {};
  31.     for i=1,#inp do
  32.       out[i]=fn(inp[i]);
  33.     end
  34.     return unpack(out);
  35. end
  36.  
  37. function DEBUG_DUMP( t , fn, ... )
  38.     if not fn then fn = print; end
  39.     local msg = "";
  40.     local ignore = {...};
  41.  
  42.     for k,v in pairs(t) do
  43.       local vstr;
  44.       if k==ign then
  45.         vstr = "(ignored)";
  46.       elseif v == t then
  47.         vstr = "(SELF)";
  48.       else
  49.         vstr = type(v) == "table" and serializeTablePrettily(v, true, 2, 1, ...) or tostring(v);
  50.       end
  51.       msg = msg .. k .. "=" .. vstr .. "\n";
  52.     end
  53.  
  54.     fn(msg);
  55. end
  56.  
  57. function pad(str, length, lr, char) -- pads a string left/right with a character. lr:l/r/b
  58.   if not str then error("pad: needs string input"); end
  59.   str = tostring(str);
  60.   char = char or " ";
  61.   lr = lr:sub(1,1):lower();
  62.  
  63.   local pl = length - str:len();
  64.   if pl < 0 then pl = 0; end
  65.  
  66.   local b = lr=="b";
  67.   local l,r = (b or lr=="l"),(b or lr=="r");
  68.  
  69.   if b then pl = pl / 2; end
  70.  
  71.   local pad = char:rep(pl);
  72.   return string.format("%s%s%s%s",
  73.     "",
  74.     l and pad or "", str,
  75.     r and pad or "");
  76. end
  77.  
  78. function clear() -- shorthand func for term.clear and cur reset
  79.   term.clear(); term.setCursorPos(1,1);
  80. end
  81.  
  82. function indexOf(tbl, v) -- simple utility function for reverse table lookup
  83.     for k,w in pairs(tbl) do
  84.         if v==w then return k; end
  85.     end
  86.    
  87.     return false;
  88. end
  89.  
  90. function countPairs(tbl)
  91.     local n = 0;
  92.     for k in pairs(tbl) do n = n + 1; end
  93.     return n;
  94. end
  95.  
  96. function getFile(file)
  97.   local fh = fs.open(file, "r");
  98.   if not fh then return false; end
  99.  
  100.   return textutils.unserialize( fh.readAll() );
  101. end
  102.  
  103. function putFile(file, t)
  104.   local fh = fs.open(file, "w");
  105.   if not fh then return false; end
  106.  
  107.   fh.write( textutils.serialize(t) );
  108.   fh.close();
  109.   return true;
  110. end
  111.  
  112. -- "pretty table serialization" (robhol)
  113.  
  114. function isTableEmpty(t)
  115.     for k,v in pairs(t) do return false; end
  116.     return true;
  117. end
  118.  
  119. local function toexp(v)
  120.     if type(v) == "string" then
  121.         return "\"" .. tostring(v) .. "\"";
  122.     end
  123.     return tostring(v);
  124. end
  125.  
  126. function serializeTablePrettily(tbl, includeKeys, inddepth, lvl, ...)
  127.  
  128.     local lvl = lvl or 1;
  129.     local indent = " ";
  130.     local inddepth = inddepth or 2;
  131.  
  132.     local ignore = {...};
  133.  
  134.     local str = indent:rep(inddepth * (lvl-1)) .. "{\n";
  135.    
  136.     for k, v in pairs(tbl) do
  137.  
  138.         local line = false;
  139.         local newline = false;
  140.         local t = type(v);
  141.  
  142.         if indexOf(ignore, k) then
  143.           line = "(ignored)";
  144.           error("ignored");
  145.         end
  146.  
  147.         if t == "table" and not isTableEmpty(v) then
  148.             line = serializeTablePrettily(v, includeKeys, inddepth, lvl+1);
  149.             newline = true;
  150.         else
  151.             if t == "function" then
  152.                 --error("cannot serialize functions");
  153.                 line = "\"\" -- function skipped";
  154.             elseif t == "table" then --empty!
  155.                 line = "{}";
  156.             else
  157.                 line = toexp(v);
  158.             end
  159.         end
  160.  
  161.         line = indent:rep(inddepth * (lvl)) .. (includeKeys and "[" .. toexp(k) .. "] = " or "") .. (newline and "\n" or "") ..  line;
  162.         str = str .. line .. ",\n";
  163.  
  164.     end
  165.  
  166.     return str:sub(1, #str-2) .. "\n" .. indent:rep(inddepth * (lvl-1)) .. "}"; --remove last comma and \n
  167.  
  168. end
  169. --end of table serialization
  170.  
  171.  
  172.  
  173. --     getArgs - simplified argument handling (robhol)
  174. --      usage: flags, args = getArgs({...}, "ab?c") - register flags a, b and c, b does not have a value (presence only)
  175. --    program: prog -a 42 -b -c n 9001 9002
  176. --              OR
  177. --             prog -abc 42 n 9001 9002
  178. --             > flags={a=42 b=true c="n") args={9001 9002}
  179.  
  180. function getArgs(xargs, sformat)
  181.  
  182.     local iargs, flags, rargs, poflags = {}, {}, {}, {};
  183.    
  184.     --duplicate the args table, we'll be playing rough with it
  185.     --we'll also expand multiflags (-abc -> -a -b -c)
  186.     for k, v in ipairs(xargs) do
  187.         local mflag = v:match("-(%a+)");
  188.         if mflag then
  189.             for mf in mflag:gmatch("%a") do
  190.                 table.insert(iargs, "-" .. mf)
  191.             end
  192.         else
  193.             table.insert(iargs, v);
  194.         end
  195.     end
  196.    
  197.     for fk, n in sformat:gmatch("(%a)(\??)") do
  198.         if fk then
  199.             poflags[fk] = (n=="?");
  200.         end
  201.     end
  202.    
  203.     while #iargs > 0 do
  204.         local settingFlag = false;
  205.        
  206.         for k, v in ipairs(iargs) do
  207.             local curFlag = v:match("-%a+");
  208.            
  209.             if not curFlag then
  210.                 if settingFlag then
  211.                     --value and we're setting a flag! match!
  212.                     flags[settingFlag:sub(2)] = v;
  213.                     table.remove(iargs, k);
  214.                     table.remove(iargs, indexOf(iargs, settingFlag));
  215.                     settingFlag = false;
  216.                     break;
  217.                 else
  218.                     --value and no associated flag, put into rargs and fekkoff
  219.                     table.remove(iargs, k);
  220.                     table.insert(rargs, v);
  221.                     break;
  222.                 end
  223.             else
  224.                 if not settingFlag then
  225.                     --flag and we're not currently setting one!
  226.                    
  227.                     if poflags[curFlag:sub(2)] then --is this a "presence only" flag?
  228.                         flags[curFlag:sub(2)] = true;
  229.                         table.remove(iargs, k);
  230.                         break;
  231.                     else
  232.                         settingFlag = curFlag;
  233.                     end
  234.                 end
  235.                 --else: do nothing (ignore flags immediately after other flags)
  236.             end
  237.            
  238.         end
  239.        
  240.         if settingFlag then
  241.             flags[settingFlag] = true;
  242.             table.remove(iargs, indexOf(iargs, settingFlag));
  243.             settingFlag = false;
  244.         end
  245.        
  246.     end
  247.    
  248.     return flags, rargs;
  249. end
  250.  
  251. --END OF GETARGS
  252.  
  253. --table copying functions ninjaed from the lua wiki
  254. -- http://lua-users.org/wiki/CopyTable
  255. function shallowcopy(orig)
  256.     local orig_type = type(orig)
  257.     local copy
  258.     if orig_type == 'table' then
  259.         copy = {}
  260.         for orig_key, orig_value in pairs(orig) do
  261.             copy[orig_key] = orig_value
  262.         end
  263.     else -- number, string, boolean, etc
  264.         copy = orig
  265.     end
  266.     return copy
  267. end
  268.  
  269. function deepcopy(orig)
  270.     local orig_type = type(orig)
  271.     local copy
  272.     if orig_type == 'table' then
  273.         copy = {}
  274.         for orig_key, orig_value in next, orig, nil do
  275.             copy[deepcopy(orig_key)] = deepcopy(orig_value)
  276.         end
  277.         setmetatable(copy, deepcopy(getmetatable(orig)))
  278.     else -- number, string, boolean, etc
  279.         copy = orig
  280.     end
  281.     return copy
  282. end
  283.  
  284.  
  285. -- ARCFOUR implementation in pure Lua
  286. -- Copyright 2008 Rob Kendrick <rjek@rjek.com>
  287. -- Distributed under the MIT licence
  288.  
  289. local function make_byte_table(bits)
  290.     local f = { }
  291.     for i = 0, 255 do
  292.         f[i] = { }
  293.     end
  294.    
  295.     f[0][0] = bits[1] * 255
  296.  
  297.     local m = 1
  298.    
  299.     for k = 0, 7 do
  300.         for i = 0, m - 1 do
  301.             for j = 0, m - 1 do
  302.                 local fij = f[i][j] - bits[1] * m
  303.                 f[i  ][j+m] = fij + bits[2] * m
  304.                 f[i+m][j  ] = fij + bits[3] * m
  305.                 f[i+m][j+m] = fij + bits[4] * m
  306.             end
  307.         end
  308.         m = m * 2
  309.     end
  310.    
  311.     return f
  312. end
  313.  
  314. local byte_xor = make_byte_table { 0, 1, 1, 0 }
  315.  
  316. local function generate(self, count)
  317.     local S, i, j = self.S, self.i, self.j
  318.     local o = { }
  319.     local char = string.char
  320.    
  321.     for z = 1, count do
  322.         i = (i + 1) % 256
  323.         j = (j + S[i]) % 256
  324.         S[i], S[j] = S[j], S[i]
  325.         o[z] = char(S[(S[i] + S[j]) % 256])
  326.     end
  327.    
  328.     self.i, self.j = i, j
  329.     return table.concat(o)
  330. end
  331.  
  332. local function cipher(self, plaintext)
  333.     local pad = generate(self, #plaintext)
  334.     local r = { }
  335.     local byte = string.byte
  336.     local char = string.char
  337.    
  338.     for i = 1, #plaintext do
  339.         r[i] = char(byte_xor[byte(plaintext, i)][byte(pad, i)])
  340.     end
  341.    
  342.     return table.concat(r)
  343. end
  344.  
  345. local function schedule(self, key)
  346.     local S = self.S
  347.     local j, kz = 0, #key
  348.     local byte = string.byte
  349.    
  350.     for i = 0, 255 do
  351.         j = (j + S[i] + byte(key, (i % kz) + 1)) % 256;
  352.         S[i], S[j] = S[j], S[i]
  353.     end
  354. end
  355.  
  356. local arcfour={};
  357. arcfour.new = function (key)
  358.     local S = { }
  359.     local r = {
  360.         S = S, i = 0, j = 0,
  361.         generate = generate,
  362.         cipher = cipher,
  363.         schedule = schedule
  364.     }
  365.    
  366.     for i = 0, 255 do
  367.         S[i] = i
  368.     end
  369.    
  370.     if key then
  371.         r:schedule(key)
  372.     end
  373.    
  374.     return r   
  375. end
  376.  
  377. function arc4(plain, key) -- simple wrapper (robhol)
  378.     local state = arcfour.new(key);
  379.     state:generate(3072);
  380.     return state:cipher(plain);
  381. end
  382. -- END OF ARCFOUR
  383.  
  384. --[[
  385. -- SHA-1 secure hash computation, and HMAC-SHA1 signature computation,
  386. -- Latest version always at:  http://regex.info/blog/lua/sha1
  387. --
  388. -- Copyright 2009 Jeffrey Friedl
  389. -- jfriedl@yahoo.com
  390. -- http://regex.info/blog/
  391.  
  392. -- Version 1 [May 28, 2009]]
  393.  
  394. -- Return a W32 object for the number zero
  395. local function ZERO()
  396.    return {
  397.       false, false, false, false,     false, false, false, false,
  398.       false, false, false, false,     false, false, false, false,
  399.       false, false, false, false,     false, false, false, false,
  400.       false, false, false, false,     false, false, false, false,
  401.    }
  402. end
  403.  
  404. local hex_to_bits = {
  405.    ["0"] = { false, false, false, false },
  406.    ["1"] = { false, false, false, true  },
  407.    ["2"] = { false, false, true,  false },
  408.    ["3"] = { false, false, true,  true  },
  409.  
  410.    ["4"] = { false, true,  false, false },
  411.    ["5"] = { false, true,  false, true  },
  412.    ["6"] = { false, true,  true,  false },
  413.    ["7"] = { false, true,  true,  true  },
  414.  
  415.    ["8"] = { true,  false, false, false },
  416.    ["9"] = { true,  false, false, true  },
  417.    ["A"] = { true,  false, true,  false },
  418.    ["B"] = { true,  false, true,  true  },
  419.  
  420.    ["C"] = { true,  true,  false, false },
  421.    ["D"] = { true,  true,  false, true  },
  422.    ["E"] = { true,  true,  true,  false },
  423.    ["F"] = { true,  true,  true,  true  },
  424.  
  425.    ["a"] = { true,  false, true,  false },
  426.    ["b"] = { true,  false, true,  true  },
  427.    ["c"] = { true,  true,  false, false },
  428.    ["d"] = { true,  true,  false, true  },
  429.    ["e"] = { true,  true,  true,  false },
  430.    ["f"] = { true,  true,  true,  true  },
  431. }
  432.  
  433. -- Given a string of 8 hex digits, return a W32 object representing that number
  434. local function from_hex(hex)
  435.  
  436.    assert(type(hex) == 'string')
  437.    assert(hex:match('^[0123456789abcdefABCDEF]+$'))
  438.    assert(#hex == 8)
  439.  
  440.    local W32 = { }
  441.  
  442.    for letter in hex:gmatch('.') do
  443.       local b = hex_to_bits[letter]
  444.       assert(b)
  445.       table.insert(W32, 1, b[1])
  446.       table.insert(W32, 1, b[2])
  447.       table.insert(W32, 1, b[3])
  448.       table.insert(W32, 1, b[4])
  449.    end
  450.  
  451.    return W32
  452. end
  453.  
  454. local function COPY(old)
  455.    local W32 = { }
  456.    for k,v in pairs(old) do
  457.       W32[k] = v
  458.    end
  459.  
  460.    return W32
  461. end
  462.  
  463. local function ADD(first, ...)
  464.  
  465.    local a = COPY(first)
  466.  
  467.    local C, b, sum
  468.  
  469.    for v = 1, select('#', ...) do
  470.       b = select(v, ...)
  471.       C = 0
  472.  
  473.       for i = 1, #a do
  474.          sum = (a[i] and 1 or 0)
  475.              + (b[i] and 1 or 0)
  476.              + C
  477.  
  478.          if sum == 0 then
  479.             a[i] = false
  480.             C    = 0
  481.          elseif sum == 1 then
  482.             a[i] = true
  483.             C    = 0
  484.          elseif sum == 2 then
  485.             a[i] = false
  486.             C    = 1
  487.          else
  488.             a[i] = true
  489.             C    = 1
  490.          end
  491.       end
  492.       -- we drop any ending carry
  493.  
  494.    end
  495.  
  496.    return a
  497. end
  498.  
  499. local function XOR(first, ...)
  500.  
  501.    local a = COPY(first)
  502.    local b
  503.    for v = 1, select('#', ...) do
  504.       b = select(v, ...)
  505.       for i = 1, #a do
  506.          a[i] = a[i] ~= b[i]
  507.       end
  508.    end
  509.  
  510.    return a
  511.  
  512. end
  513.  
  514. local function AND(a, b)
  515.  
  516.    local c = ZERO()
  517.  
  518.    for i = 1, #a do
  519.       -- only need to set true bits; other bits remain false
  520.       if  a[i] and b[i] then
  521.          c[i] = true
  522.       end
  523.    end
  524.  
  525.    return c
  526. end
  527.  
  528. local function OR(a, b)
  529.  
  530.    local c = ZERO()
  531.  
  532.    for i = 1, #a do
  533.       -- only need to set true bits; other bits remain false
  534.       if  a[i] or b[i] then
  535.          c[i] = true
  536.       end
  537.    end
  538.  
  539.    return c
  540. end
  541.  
  542. local function OR3(a, b, c)
  543.  
  544.    local d = ZERO()
  545.  
  546.    for i = 1, #a do
  547.       -- only need to set true bits; other bits remain false
  548.       if a[i] or b[i] or c[i] then
  549.          d[i] = true
  550.       end
  551.    end
  552.  
  553.    return d
  554. end
  555.  
  556. local function NOT(a)
  557.  
  558.    local b = ZERO()
  559.  
  560.    for i = 1, #a do
  561.       -- only need to set true bits; other bits remain false
  562.       if not a[i] then
  563.          b[i] = true
  564.       end
  565.    end
  566.  
  567.    return b
  568. end
  569.  
  570. local function ROTATE(bits, a)
  571.  
  572.    local b = COPY(a)
  573.  
  574.    while bits > 0 do
  575.       bits = bits - 1
  576.       table.insert(b, 1, table.remove(b))
  577.    end
  578.  
  579.    return b
  580.  
  581. end
  582.  
  583.  
  584. local binary_to_hex = {
  585.    ["0000"] = "0",
  586.    ["0001"] = "1",
  587.    ["0010"] = "2",
  588.    ["0011"] = "3",
  589.    ["0100"] = "4",
  590.    ["0101"] = "5",
  591.    ["0110"] = "6",
  592.    ["0111"] = "7",
  593.    ["1000"] = "8",
  594.    ["1001"] = "9",
  595.    ["1010"] = "a",
  596.    ["1011"] = "b",
  597.    ["1100"] = "c",
  598.    ["1101"] = "d",
  599.    ["1110"] = "e",
  600.    ["1111"] = "f",
  601. }
  602.  
  603. local function asHEX(a)
  604.  
  605.    local hex = ""
  606.    local i = 1
  607.    while i < #a do
  608.       local binary = (a[i + 3] and '1' or '0')
  609.                      ..
  610.                      (a[i + 2] and '1' or '0')
  611.                      ..
  612.                      (a[i + 1] and '1' or '0')
  613.                      ..
  614.                      (a[i + 0] and '1' or '0')
  615.  
  616.       hex = binary_to_hex[binary] .. hex
  617.  
  618.       i = i + 4
  619.    end
  620.  
  621.    return hex
  622.  
  623. end
  624.  
  625. local x67452301 = from_hex("67452301")
  626. local xEFCDAB89 = from_hex("EFCDAB89")
  627. local x98BADCFE = from_hex("98BADCFE")
  628. local x10325476 = from_hex("10325476")
  629. local xC3D2E1F0 = from_hex("C3D2E1F0")
  630.  
  631. local x5A827999 = from_hex("5A827999")
  632. local x6ED9EBA1 = from_hex("6ED9EBA1")
  633. local x8F1BBCDC = from_hex("8F1BBCDC")
  634. local xCA62C1D6 = from_hex("CA62C1D6")
  635.  
  636.  
  637. function sha1(msg)
  638.  
  639.    assert(type(msg) == 'string')
  640.    assert(#msg < 0x7FFFFFFF) -- have no idea what would happen if it were large
  641.  
  642.    local H0 = x67452301
  643.    local H1 = xEFCDAB89
  644.    local H2 = x98BADCFE
  645.    local H3 = x10325476
  646.    local H4 = xC3D2E1F0
  647.  
  648.    local msg_len_in_bits = #msg * 8
  649.  
  650.    local first_append = string.char(0x80) -- append a '1' bit plus seven '0' bits
  651.  
  652.    local non_zero_message_bytes = #msg +1 +8 -- the +1 is the appended bit 1, the +8 are for the final appended length
  653.    local current_mod = non_zero_message_bytes % 64
  654.    local second_append = ""
  655.    if current_mod ~= 0 then
  656.       second_append = string.rep(string.char(0), 64 - current_mod)
  657.    end
  658.  
  659.    -- now to append the length as a 64-bit number.
  660.    local B1, R1 = math.modf(msg_len_in_bits  / 0x01000000)
  661.    local B2, R2 = math.modf( 0x01000000 * R1 / 0x00010000)
  662.    local B3, R3 = math.modf( 0x00010000 * R2 / 0x00000100)
  663.    local B4     =            0x00000100 * R3
  664.  
  665.    local L64 = string.char( 0) .. string.char( 0) .. string.char( 0) .. string.char( 0) -- high 32 bits
  666.             .. string.char(B1) .. string.char(B2) .. string.char(B3) .. string.char(B4) --  low 32 bits
  667.  
  668.  
  669.  
  670.    msg = msg .. first_append .. second_append .. L64        
  671.  
  672.    assert(#msg % 64 == 0)
  673.  
  674.    --local fd = io.open("/tmp/msg", "wb")
  675.    --fd:write(msg)
  676.    --fd:close()
  677.  
  678.    local chunks = #msg / 64
  679.  
  680.    local W = { }
  681.    local start, A, B, C, D, E, f, K, TEMP
  682.    local chunk = 0
  683.  
  684.    while chunk < chunks do
  685.       --
  686.       -- break chunk up into W[0] through W[15]
  687.       --
  688.       start = chunk * 64 + 1
  689.       chunk = chunk + 1
  690.  
  691.       for t = 0, 15 do
  692.          W[t] = from_hex(string.format("%02x%02x%02x%02x", msg:byte(start, start + 3)))
  693.          start = start + 4
  694.       end
  695.  
  696.       --
  697.       -- build W[16] through W[79]
  698.       --
  699.       for t = 16, 79 do
  700.          -- For t = 16 to 79 let Wt = S1(Wt-3 XOR Wt-8 XOR Wt-14 XOR Wt-16).
  701.          W[t] = ROTATE(1, XOR(W[t-3], W[t-8], W[t-14], W[t-16]))
  702.       end
  703.  
  704.       A = H0
  705.       B = H1
  706.       C = H2
  707.       D = H3
  708.       E = H4
  709.  
  710.       for t = 0, 79 do
  711.          if t <= 19 then
  712.             -- (B AND C) OR ((NOT B) AND D)
  713.             f = OR(AND(B, C), AND(NOT(B), D))
  714.             K = x5A827999
  715.          elseif t <= 39 then
  716.             -- B XOR C XOR D
  717.             f = XOR(B, C, D)
  718.             K = x6ED9EBA1
  719.          elseif t <= 59 then
  720.             -- (B AND C) OR (B AND D) OR (C AND D
  721.             f = OR3(AND(B, C), AND(B, D), AND(C, D))
  722.             K = x8F1BBCDC
  723.          else
  724.             -- B XOR C XOR D
  725.             f = XOR(B, C, D)
  726.             K = xCA62C1D6
  727.          end
  728.  
  729.          -- TEMP = S5(A) + ft(B,C,D) + E + Wt + Kt;
  730.          TEMP = ADD(ROTATE(5, A), f, E, W[t], K)
  731.  
  732.          --E = D;   D = C;    C = S30(B);   B = A;   A = TEMP;
  733.          E = D
  734.          D = C
  735.          C = ROTATE(30, B)
  736.          B = A
  737.          A = TEMP
  738.  
  739.          --printf("t = %2d: %s  %s  %s  %s  %s", t, A:HEX(), B:HEX(), C:HEX(), D:HEX(), E:HEX())
  740.       end
  741.  
  742.       -- Let H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E.
  743.       H0 = ADD(H0, A)
  744.       H1 = ADD(H1, B)
  745.       H2 = ADD(H2, C)
  746.       H3 = ADD(H3, D)
  747.       H4 = ADD(H4, E)
  748.    end
  749.  
  750.    return asHEX(H0) .. asHEX(H1) .. asHEX(H2) .. asHEX(H3) .. asHEX(H4)
  751. end
  752.  
  753. local function hex_to_binary(hex)
  754.    return hex:gsub('..', function(hexval)
  755.                             return string.char(tonumber(hexval, 16))
  756.                          end)
  757. end
  758.  
  759. function sha1_binary(msg)
  760.    return hex_to_binary(sha1(msg))
  761. end
  762.  
  763. local xor_with_0x5c = {
  764.    [string.char(  0)] = string.char( 92),   [string.char(  1)] = string.char( 93),
  765.    [string.char(  2)] = string.char( 94),   [string.char(  3)] = string.char( 95),
  766.    [string.char(  4)] = string.char( 88),   [string.char(  5)] = string.char( 89),
  767.    [string.char(  6)] = string.char( 90),   [string.char(  7)] = string.char( 91),
  768.    [string.char(  8)] = string.char( 84),   [string.char(  9)] = string.char( 85),
  769.    [string.char( 10)] = string.char( 86),   [string.char( 11)] = string.char( 87),
  770.    [string.char( 12)] = string.char( 80),   [string.char( 13)] = string.char( 81),
  771.    [string.char( 14)] = string.char( 82),   [string.char( 15)] = string.char( 83),
  772.    [string.char( 16)] = string.char( 76),   [string.char( 17)] = string.char( 77),
  773.    [string.char( 18)] = string.char( 78),   [string.char( 19)] = string.char( 79),
  774.    [string.char( 20)] = string.char( 72),   [string.char( 21)] = string.char( 73),
  775.    [string.char( 22)] = string.char( 74),   [string.char( 23)] = string.char( 75),
  776.    [string.char( 24)] = string.char( 68),   [string.char( 25)] = string.char( 69),
  777.    [string.char( 26)] = string.char( 70),   [string.char( 27)] = string.char( 71),
  778.    [string.char( 28)] = string.char( 64),   [string.char( 29)] = string.char( 65),
  779.    [string.char( 30)] = string.char( 66),   [string.char( 31)] = string.char( 67),
  780.    [string.char( 32)] = string.char(124),   [string.char( 33)] = string.char(125),
  781.    [string.char( 34)] = string.char(126),   [string.char( 35)] = string.char(127),
  782.    [string.char( 36)] = string.char(120),   [string.char( 37)] = string.char(121),
  783.    [string.char( 38)] = string.char(122),   [string.char( 39)] = string.char(123),
  784.    [string.char( 40)] = string.char(116),   [string.char( 41)] = string.char(117),
  785.    [string.char( 42)] = string.char(118),   [string.char( 43)] = string.char(119),
  786.    [string.char( 44)] = string.char(112),   [string.char( 45)] = string.char(113),
  787.    [string.char( 46)] = string.char(114),   [string.char( 47)] = string.char(115),
  788.    [string.char( 48)] = string.char(108),   [string.char( 49)] = string.char(109),
  789.    [string.char( 50)] = string.char(110),   [string.char( 51)] = string.char(111),
  790.    [string.char( 52)] = string.char(104),   [string.char( 53)] = string.char(105),
  791.    [string.char( 54)] = string.char(106),   [string.char( 55)] = string.char(107),
  792.    [string.char( 56)] = string.char(100),   [string.char( 57)] = string.char(101),
  793.    [string.char( 58)] = string.char(102),   [string.char( 59)] = string.char(103),
  794.    [string.char( 60)] = string.char( 96),   [string.char( 61)] = string.char( 97),
  795.    [string.char( 62)] = string.char( 98),   [string.char( 63)] = string.char( 99),
  796.    [string.char( 64)] = string.char( 28),   [string.char( 65)] = string.char( 29),
  797.    [string.char( 66)] = string.char( 30),   [string.char( 67)] = string.char( 31),
  798.    [string.char( 68)] = string.char( 24),   [string.char( 69)] = string.char( 25),
  799.    [string.char( 70)] = string.char( 26),   [string.char( 71)] = string.char( 27),
  800.    [string.char( 72)] = string.char( 20),   [string.char( 73)] = string.char( 21),
  801.    [string.char( 74)] = string.char( 22),   [string.char( 75)] = string.char( 23),
  802.    [string.char( 76)] = string.char( 16),   [string.char( 77)] = string.char( 17),
  803.    [string.char( 78)] = string.char( 18),   [string.char( 79)] = string.char( 19),
  804.    [string.char( 80)] = string.char( 12),   [string.char( 81)] = string.char( 13),
  805.    [string.char( 82)] = string.char( 14),   [string.char( 83)] = string.char( 15),
  806.    [string.char( 84)] = string.char(  8),   [string.char( 85)] = string.char(  9),
  807.    [string.char( 86)] = string.char( 10),   [string.char( 87)] = string.char( 11),
  808.    [string.char( 88)] = string.char(  4),   [string.char( 89)] = string.char(  5),
  809.    [string.char( 90)] = string.char(  6),   [string.char( 91)] = string.char(  7),
  810.    [string.char( 92)] = string.char(  0),   [string.char( 93)] = string.char(  1),
  811.    [string.char( 94)] = string.char(  2),   [string.char( 95)] = string.char(  3),
  812.    [string.char( 96)] = string.char( 60),   [string.char( 97)] = string.char( 61),
  813.    [string.char( 98)] = string.char( 62),   [string.char( 99)] = string.char( 63),
  814.    [string.char(100)] = string.char( 56),   [string.char(101)] = string.char( 57),
  815.    [string.char(102)] = string.char( 58),   [string.char(103)] = string.char( 59),
  816.    [string.char(104)] = string.char( 52),   [string.char(105)] = string.char( 53),
  817.    [string.char(106)] = string.char( 54),   [string.char(107)] = string.char( 55),
  818.    [string.char(108)] = string.char( 48),   [string.char(109)] = string.char( 49),
  819.    [string.char(110)] = string.char( 50),   [string.char(111)] = string.char( 51),
  820.    [string.char(112)] = string.char( 44),   [string.char(113)] = string.char( 45),
  821.    [string.char(114)] = string.char( 46),   [string.char(115)] = string.char( 47),
  822.    [string.char(116)] = string.char( 40),   [string.char(117)] = string.char( 41),
  823.    [string.char(118)] = string.char( 42),   [string.char(119)] = string.char( 43),
  824.    [string.char(120)] = string.char( 36),   [string.char(121)] = string.char( 37),
  825.    [string.char(122)] = string.char( 38),   [string.char(123)] = string.char( 39),
  826.    [string.char(124)] = string.char( 32),   [string.char(125)] = string.char( 33),
  827.    [string.char(126)] = string.char( 34),   [string.char(127)] = string.char( 35),
  828.    [string.char(128)] = string.char(220),   [string.char(129)] = string.char(221),
  829.    [string.char(130)] = string.char(222),   [string.char(131)] = string.char(223),
  830.    [string.char(132)] = string.char(216),   [string.char(133)] = string.char(217),
  831.    [string.char(134)] = string.char(218),   [string.char(135)] = string.char(219),
  832.    [string.char(136)] = string.char(212),   [string.char(137)] = string.char(213),
  833.    [string.char(138)] = string.char(214),   [string.char(139)] = string.char(215),
  834.    [string.char(140)] = string.char(208),   [string.char(141)] = string.char(209),
  835.    [string.char(142)] = string.char(210),   [string.char(143)] = string.char(211),
  836.    [string.char(144)] = string.char(204),   [string.char(145)] = string.char(205),
  837.    [string.char(146)] = string.char(206),   [string.char(147)] = string.char(207),
  838.    [string.char(148)] = string.char(200),   [string.char(149)] = string.char(201),
  839.    [string.char(150)] = string.char(202),   [string.char(151)] = string.char(203),
  840.    [string.char(152)] = string.char(196),   [string.char(153)] = string.char(197),
  841.    [string.char(154)] = string.char(198),   [string.char(155)] = string.char(199),
  842.    [string.char(156)] = string.char(192),   [string.char(157)] = string.char(193),
  843.    [string.char(158)] = string.char(194),   [string.char(159)] = string.char(195),
  844.    [string.char(160)] = string.char(252),   [string.char(161)] = string.char(253),
  845.    [string.char(162)] = string.char(254),   [string.char(163)] = string.char(255),
  846.    [string.char(164)] = string.char(248),   [string.char(165)] = string.char(249),
  847.    [string.char(166)] = string.char(250),   [string.char(167)] = string.char(251),
  848.    [string.char(168)] = string.char(244),   [string.char(169)] = string.char(245),
  849.    [string.char(170)] = string.char(246),   [string.char(171)] = string.char(247),
  850.    [string.char(172)] = string.char(240),   [string.char(173)] = string.char(241),
  851.    [string.char(174)] = string.char(242),   [string.char(175)] = string.char(243),
  852.    [string.char(176)] = string.char(236),   [string.char(177)] = string.char(237),
  853.    [string.char(178)] = string.char(238),   [string.char(179)] = string.char(239),
  854.    [string.char(180)] = string.char(232),   [string.char(181)] = string.char(233),
  855.    [string.char(182)] = string.char(234),   [string.char(183)] = string.char(235),
  856.    [string.char(184)] = string.char(228),   [string.char(185)] = string.char(229),
  857.    [string.char(186)] = string.char(230),   [string.char(187)] = string.char(231),
  858.    [string.char(188)] = string.char(224),   [string.char(189)] = string.char(225),
  859.    [string.char(190)] = string.char(226),   [string.char(191)] = string.char(227),
  860.    [string.char(192)] = string.char(156),   [string.char(193)] = string.char(157),
  861.    [string.char(194)] = string.char(158),   [string.char(195)] = string.char(159),
  862.    [string.char(196)] = string.char(152),   [string.char(197)] = string.char(153),
  863.    [string.char(198)] = string.char(154),   [string.char(199)] = string.char(155),
  864.    [string.char(200)] = string.char(148),   [string.char(201)] = string.char(149),
  865.    [string.char(202)] = string.char(150),   [string.char(203)] = string.char(151),
  866.    [string.char(204)] = string.char(144),   [string.char(205)] = string.char(145),
  867.    [string.char(206)] = string.char(146),   [string.char(207)] = string.char(147),
  868.    [string.char(208)] = string.char(140),   [string.char(209)] = string.char(141),
  869.    [string.char(210)] = string.char(142),   [string.char(211)] = string.char(143),
  870.    [string.char(212)] = string.char(136),   [string.char(213)] = string.char(137),
  871.    [string.char(214)] = string.char(138),   [string.char(215)] = string.char(139),
  872.    [string.char(216)] = string.char(132),   [string.char(217)] = string.char(133),
  873.    [string.char(218)] = string.char(134),   [string.char(219)] = string.char(135),
  874.    [string.char(220)] = string.char(128),   [string.char(221)] = string.char(129),
  875.    [string.char(222)] = string.char(130),   [string.char(223)] = string.char(131),
  876.    [string.char(224)] = string.char(188),   [string.char(225)] = string.char(189),
  877.    [string.char(226)] = string.char(190),   [string.char(227)] = string.char(191),
  878.    [string.char(228)] = string.char(184),   [string.char(229)] = string.char(185),
  879.    [string.char(230)] = string.char(186),   [string.char(231)] = string.char(187),
  880.    [string.char(232)] = string.char(180),   [string.char(233)] = string.char(181),
  881.    [string.char(234)] = string.char(182),   [string.char(235)] = string.char(183),
  882.    [string.char(236)] = string.char(176),   [string.char(237)] = string.char(177),
  883.    [string.char(238)] = string.char(178),   [string.char(239)] = string.char(179),
  884.    [string.char(240)] = string.char(172),   [string.char(241)] = string.char(173),
  885.    [string.char(242)] = string.char(174),   [string.char(243)] = string.char(175),
  886.    [string.char(244)] = string.char(168),   [string.char(245)] = string.char(169),
  887.    [string.char(246)] = string.char(170),   [string.char(247)] = string.char(171),
  888.    [string.char(248)] = string.char(164),   [string.char(249)] = string.char(165),
  889.    [string.char(250)] = string.char(166),   [string.char(251)] = string.char(167),
  890.    [string.char(252)] = string.char(160),   [string.char(253)] = string.char(161),
  891.    [string.char(254)] = string.char(162),   [string.char(255)] = string.char(163),
  892. }
  893.  
  894. local xor_with_0x36 = {
  895.    [string.char(  0)] = string.char( 54),   [string.char(  1)] = string.char( 55),
  896.    [string.char(  2)] = string.char( 52),   [string.char(  3)] = string.char( 53),
  897.    [string.char(  4)] = string.char( 50),   [string.char(  5)] = string.char( 51),
  898.    [string.char(  6)] = string.char( 48),   [string.char(  7)] = string.char( 49),
  899.    [string.char(  8)] = string.char( 62),   [string.char(  9)] = string.char( 63),
  900.    [string.char( 10)] = string.char( 60),   [string.char( 11)] = string.char( 61),
  901.    [string.char( 12)] = string.char( 58),   [string.char( 13)] = string.char( 59),
  902.    [string.char( 14)] = string.char( 56),   [string.char( 15)] = string.char( 57),
  903.    [string.char( 16)] = string.char( 38),   [string.char( 17)] = string.char( 39),
  904.    [string.char( 18)] = string.char( 36),   [string.char( 19)] = string.char( 37),
  905.    [string.char( 20)] = string.char( 34),   [string.char( 21)] = string.char( 35),
  906.    [string.char( 22)] = string.char( 32),   [string.char( 23)] = string.char( 33),
  907.    [string.char( 24)] = string.char( 46),   [string.char( 25)] = string.char( 47),
  908.    [string.char( 26)] = string.char( 44),   [string.char( 27)] = string.char( 45),
  909.    [string.char( 28)] = string.char( 42),   [string.char( 29)] = string.char( 43),
  910.    [string.char( 30)] = string.char( 40),   [string.char( 31)] = string.char( 41),
  911.    [string.char( 32)] = string.char( 22),   [string.char( 33)] = string.char( 23),
  912.    [string.char( 34)] = string.char( 20),   [string.char( 35)] = string.char( 21),
  913.    [string.char( 36)] = string.char( 18),   [string.char( 37)] = string.char( 19),
  914.    [string.char( 38)] = string.char( 16),   [string.char( 39)] = string.char( 17),
  915.    [string.char( 40)] = string.char( 30),   [string.char( 41)] = string.char( 31),
  916.    [string.char( 42)] = string.char( 28),   [string.char( 43)] = string.char( 29),
  917.    [string.char( 44)] = string.char( 26),   [string.char( 45)] = string.char( 27),
  918.    [string.char( 46)] = string.char( 24),   [string.char( 47)] = string.char( 25),
  919.    [string.char( 48)] = string.char(  6),   [string.char( 49)] = string.char(  7),
  920.    [string.char( 50)] = string.char(  4),   [string.char( 51)] = string.char(  5),
  921.    [string.char( 52)] = string.char(  2),   [string.char( 53)] = string.char(  3),
  922.    [string.char( 54)] = string.char(  0),   [string.char( 55)] = string.char(  1),
  923.    [string.char( 56)] = string.char( 14),   [string.char( 57)] = string.char( 15),
  924.    [string.char( 58)] = string.char( 12),   [string.char( 59)] = string.char( 13),
  925.    [string.char( 60)] = string.char( 10),   [string.char( 61)] = string.char( 11),
  926.    [string.char( 62)] = string.char(  8),   [string.char( 63)] = string.char(  9),
  927.    [string.char( 64)] = string.char(118),   [string.char( 65)] = string.char(119),
  928.    [string.char( 66)] = string.char(116),   [string.char( 67)] = string.char(117),
  929.    [string.char( 68)] = string.char(114),   [string.char( 69)] = string.char(115),
  930.    [string.char( 70)] = string.char(112),   [string.char( 71)] = string.char(113),
  931.    [string.char( 72)] = string.char(126),   [string.char( 73)] = string.char(127),
  932.    [string.char( 74)] = string.char(124),   [string.char( 75)] = string.char(125),
  933.    [string.char( 76)] = string.char(122),   [string.char( 77)] = string.char(123),
  934.    [string.char( 78)] = string.char(120),   [string.char( 79)] = string.char(121),
  935.    [string.char( 80)] = string.char(102),   [string.char( 81)] = string.char(103),
  936.    [string.char( 82)] = string.char(100),   [string.char( 83)] = string.char(101),
  937.    [string.char( 84)] = string.char( 98),   [string.char( 85)] = string.char( 99),
  938.    [string.char( 86)] = string.char( 96),   [string.char( 87)] = string.char( 97),
  939.    [string.char( 88)] = string.char(110),   [string.char( 89)] = string.char(111),
  940.    [string.char( 90)] = string.char(108),   [string.char( 91)] = string.char(109),
  941.    [string.char( 92)] = string.char(106),   [string.char( 93)] = string.char(107),
  942.    [string.char( 94)] = string.char(104),   [string.char( 95)] = string.char(105),
  943.    [string.char( 96)] = string.char( 86),   [string.char( 97)] = string.char( 87),
  944.    [string.char( 98)] = string.char( 84),   [string.char( 99)] = string.char( 85),
  945.    [string.char(100)] = string.char( 82),   [string.char(101)] = string.char( 83),
  946.    [string.char(102)] = string.char( 80),   [string.char(103)] = string.char( 81),
  947.    [string.char(104)] = string.char( 94),   [string.char(105)] = string.char( 95),
  948.    [string.char(106)] = string.char( 92),   [string.char(107)] = string.char( 93),
  949.    [string.char(108)] = string.char( 90),   [string.char(109)] = string.char( 91),
  950.    [string.char(110)] = string.char( 88),   [string.char(111)] = string.char( 89),
  951.    [string.char(112)] = string.char( 70),   [string.char(113)] = string.char( 71),
  952.    [string.char(114)] = string.char( 68),   [string.char(115)] = string.char( 69),
  953.    [string.char(116)] = string.char( 66),   [string.char(117)] = string.char( 67),
  954.    [string.char(118)] = string.char( 64),   [string.char(119)] = string.char( 65),
  955.    [string.char(120)] = string.char( 78),   [string.char(121)] = string.char( 79),
  956.    [string.char(122)] = string.char( 76),   [string.char(123)] = string.char( 77),
  957.    [string.char(124)] = string.char( 74),   [string.char(125)] = string.char( 75),
  958.    [string.char(126)] = string.char( 72),   [string.char(127)] = string.char( 73),
  959.    [string.char(128)] = string.char(182),   [string.char(129)] = string.char(183),
  960.    [string.char(130)] = string.char(180),   [string.char(131)] = string.char(181),
  961.    [string.char(132)] = string.char(178),   [string.char(133)] = string.char(179),
  962.    [string.char(134)] = string.char(176),   [string.char(135)] = string.char(177),
  963.    [string.char(136)] = string.char(190),   [string.char(137)] = string.char(191),
  964.    [string.char(138)] = string.char(188),   [string.char(139)] = string.char(189),
  965.    [string.char(140)] = string.char(186),   [string.char(141)] = string.char(187),
  966.    [string.char(142)] = string.char(184),   [string.char(143)] = string.char(185),
  967.    [string.char(144)] = string.char(166),   [string.char(145)] = string.char(167),
  968.    [string.char(146)] = string.char(164),   [string.char(147)] = string.char(165),
  969.    [string.char(148)] = string.char(162),   [string.char(149)] = string.char(163),
  970.    [string.char(150)] = string.char(160),   [string.char(151)] = string.char(161),
  971.    [string.char(152)] = string.char(174),   [string.char(153)] = string.char(175),
  972.    [string.char(154)] = string.char(172),   [string.char(155)] = string.char(173),
  973.    [string.char(156)] = string.char(170),   [string.char(157)] = string.char(171),
  974.    [string.char(158)] = string.char(168),   [string.char(159)] = string.char(169),
  975.    [string.char(160)] = string.char(150),   [string.char(161)] = string.char(151),
  976.    [string.char(162)] = string.char(148),   [string.char(163)] = string.char(149),
  977.    [string.char(164)] = string.char(146),   [string.char(165)] = string.char(147),
  978.    [string.char(166)] = string.char(144),   [string.char(167)] = string.char(145),
  979.    [string.char(168)] = string.char(158),   [string.char(169)] = string.char(159),
  980.    [string.char(170)] = string.char(156),   [string.char(171)] = string.char(157),
  981.    [string.char(172)] = string.char(154),   [string.char(173)] = string.char(155),
  982.    [string.char(174)] = string.char(152),   [string.char(175)] = string.char(153),
  983.    [string.char(176)] = string.char(134),   [string.char(177)] = string.char(135),
  984.    [string.char(178)] = string.char(132),   [string.char(179)] = string.char(133),
  985.    [string.char(180)] = string.char(130),   [string.char(181)] = string.char(131),
  986.    [string.char(182)] = string.char(128),   [string.char(183)] = string.char(129),
  987.    [string.char(184)] = string.char(142),   [string.char(185)] = string.char(143),
  988.    [string.char(186)] = string.char(140),   [string.char(187)] = string.char(141),
  989.    [string.char(188)] = string.char(138),   [string.char(189)] = string.char(139),
  990.    [string.char(190)] = string.char(136),   [string.char(191)] = string.char(137),
  991.    [string.char(192)] = string.char(246),   [string.char(193)] = string.char(247),
  992.    [string.char(194)] = string.char(244),   [string.char(195)] = string.char(245),
  993.    [string.char(196)] = string.char(242),   [string.char(197)] = string.char(243),
  994.    [string.char(198)] = string.char(240),   [string.char(199)] = string.char(241),
  995.    [string.char(200)] = string.char(254),   [string.char(201)] = string.char(255),
  996.    [string.char(202)] = string.char(252),   [string.char(203)] = string.char(253),
  997.    [string.char(204)] = string.char(250),   [string.char(205)] = string.char(251),
  998.    [string.char(206)] = string.char(248),   [string.char(207)] = string.char(249),
  999.    [string.char(208)] = string.char(230),   [string.char(209)] = string.char(231),
  1000.    [string.char(210)] = string.char(228),   [string.char(211)] = string.char(229),
  1001.    [string.char(212)] = string.char(226),   [string.char(213)] = string.char(227),
  1002.    [string.char(214)] = string.char(224),   [string.char(215)] = string.char(225),
  1003.    [string.char(216)] = string.char(238),   [string.char(217)] = string.char(239),
  1004.    [string.char(218)] = string.char(236),   [string.char(219)] = string.char(237),
  1005.    [string.char(220)] = string.char(234),   [string.char(221)] = string.char(235),
  1006.    [string.char(222)] = string.char(232),   [string.char(223)] = string.char(233),
  1007.    [string.char(224)] = string.char(214),   [string.char(225)] = string.char(215),
  1008.    [string.char(226)] = string.char(212),   [string.char(227)] = string.char(213),
  1009.    [string.char(228)] = string.char(210),   [string.char(229)] = string.char(211),
  1010.    [string.char(230)] = string.char(208),   [string.char(231)] = string.char(209),
  1011.    [string.char(232)] = string.char(222),   [string.char(233)] = string.char(223),
  1012.    [string.char(234)] = string.char(220),   [string.char(235)] = string.char(221),
  1013.    [string.char(236)] = string.char(218),   [string.char(237)] = string.char(219),
  1014.    [string.char(238)] = string.char(216),   [string.char(239)] = string.char(217),
  1015.    [string.char(240)] = string.char(198),   [string.char(241)] = string.char(199),
  1016.    [string.char(242)] = string.char(196),   [string.char(243)] = string.char(197),
  1017.    [string.char(244)] = string.char(194),   [string.char(245)] = string.char(195),
  1018.    [string.char(246)] = string.char(192),   [string.char(247)] = string.char(193),
  1019.    [string.char(248)] = string.char(206),   [string.char(249)] = string.char(207),
  1020.    [string.char(250)] = string.char(204),   [string.char(251)] = string.char(205),
  1021.    [string.char(252)] = string.char(202),   [string.char(253)] = string.char(203),
  1022.    [string.char(254)] = string.char(200),   [string.char(255)] = string.char(201),
  1023. }
  1024.  
  1025.  
  1026. local blocksize = 64 -- 512 bits
  1027.  
  1028. function hmac_sha1(key, text)
  1029.    assert(type(key)  == 'string', "key passed to hmac_sha1 should be a string")
  1030.    assert(type(text) == 'string', "text passed to hmac_sha1 should be a string")
  1031.  
  1032.    if #key > blocksize then
  1033.       key = sha1_binary(key)
  1034.    end
  1035.  
  1036.    local key_xord_with_0x36 = key:gsub('.', xor_with_0x36) .. string.rep(string.char(0x36), blocksize - #key)
  1037.    local key_xord_with_0x5c = key:gsub('.', xor_with_0x5c) .. string.rep(string.char(0x5c), blocksize - #key)
  1038.  
  1039.    return sha1(key_xord_with_0x5c .. sha1_binary(key_xord_with_0x36 .. text))
  1040. end
  1041.  
  1042. function hmac_sha1_binary(key, text)
  1043.    return hex_to_binary(hmac_sha1(key, text))
  1044. end
  1045. --END OF SHA1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement