home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Networking / nmap-5.00-setup.exe / nselib / base64.lua next >
Text File  |  2009-07-06  |  4KB  |  177 lines

  1. --- Base64 encoding and decoding. Follows RFC 4648.
  2. -- @author Philip Pickering <pgpickering@gmail.com>
  3. -- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
  4.  
  5. -- thanks to Patrick Donnelly for some optimizations
  6.  
  7. module(... or "base64",package.seeall)
  8.  
  9. require 'bin'
  10.  
  11. -- todo: make metatable/index --> '' for b64dctable
  12.  
  13.  
  14. local b64table = {
  15.     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
  16.     'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  17.     'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
  18.     'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  19.     'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  20.     'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  21.     'w', 'x', 'y', 'z', '0', '1', '2', '3', 
  22.     '4', '5', '6', '7', '8', '9', '+', '/'
  23.     }
  24.     
  25. local b64dctable = {} -- efficency
  26. b64dctable['A'] = '000000'
  27. b64dctable['B'] = '000001'
  28. b64dctable['C'] = '000010'
  29. b64dctable['D'] = '000011'
  30. b64dctable['E'] = '000100'
  31. b64dctable['F'] = '000101'
  32. b64dctable['G'] = '000110'
  33. b64dctable['H'] = '000111'
  34. b64dctable['I'] = '001000'
  35. b64dctable['J'] = '001001'
  36. b64dctable['K'] = '001010'
  37. b64dctable['L'] = '001011'
  38. b64dctable['M'] = '001100'
  39. b64dctable['N'] = '001101'
  40. b64dctable['O'] = '001110'
  41. b64dctable['P'] = '001111'
  42. b64dctable['Q'] = '010000'
  43. b64dctable['R'] = '010001'
  44. b64dctable['S'] = '010010'
  45. b64dctable['T'] = '010011'
  46. b64dctable['U'] = '010100'
  47. b64dctable['V'] = '010101'
  48. b64dctable['W'] = '010110'
  49. b64dctable['X'] = '010111'
  50. b64dctable['Y'] = '011000'
  51. b64dctable['Z'] = '011001'
  52. b64dctable['a'] = '011010'
  53. b64dctable['b'] = '011011'
  54. b64dctable['c'] = '011100'
  55. b64dctable['d'] = '011101'
  56. b64dctable['e'] = '011110'
  57. b64dctable['f'] = '011111'
  58. b64dctable['g'] = '100000'
  59. b64dctable['h'] = '100001'
  60. b64dctable['i'] = '100010'
  61. b64dctable['j'] = '100011'
  62. b64dctable['k'] = '100100'
  63. b64dctable['l'] = '100101'
  64. b64dctable['m'] = '100110'
  65. b64dctable['n'] = '100111'
  66. b64dctable['o'] = '101000'
  67. b64dctable['p'] = '101001'
  68. b64dctable['q'] = '101010'
  69. b64dctable['r'] = '101011'
  70. b64dctable['s'] = '101100'
  71. b64dctable['t'] = '101101'
  72. b64dctable['u'] = '101110'
  73. b64dctable['v'] = '101111'
  74. b64dctable['w'] = '110000'
  75. b64dctable['x'] = '110001'
  76. b64dctable['y'] = '110010'
  77. b64dctable['z'] = '110011'
  78. b64dctable['0'] = '110100'
  79. b64dctable['1'] = '110101'
  80. b64dctable['2'] = '110110'
  81. b64dctable['3'] = '110111'
  82. b64dctable['4'] = '111000'
  83. b64dctable['5'] = '111001'
  84. b64dctable['6'] = '111010'
  85. b64dctable['7'] = '111011'
  86. b64dctable['8'] = '111100'
  87. b64dctable['9'] = '111101'
  88. b64dctable['+'] = '111110'
  89. b64dctable['/'] = '111111'
  90.  
  91.  
  92. local append = table.insert
  93. local substr = string.sub
  94. local bpack = bin.pack 
  95. local bunpack = bin.unpack
  96. local concat = table.concat
  97.  
  98. ---
  99. -- Encode six bits to a Base64-encoded character.
  100. -- @param bits String of six bits to be encoded.
  101. -- @return Encoded character.
  102. local function b64enc6bit(bits)
  103.     -- local byte
  104.     -- local _, byte = bunpack("C", bpack("B", "00" .. bits))
  105.     --
  106.     
  107.     -- more efficient, does the same (nb: add one to byte moved up one line):
  108.     local byte = tonumber(bits, 2) + 1
  109.     return b64table[byte]
  110. end
  111.  
  112.  
  113. ---
  114. -- Decodes a Base64-encoded character into a string of binary digits.
  115. -- @param b64byte A single base64-encoded character.
  116. -- @return String of six decoded bits.
  117. local function b64dec6bit(b64byte)
  118.     local bits = b64dctable[b64byte]
  119.     if bits then return bits end
  120.     return ''
  121. end
  122.  
  123.  
  124. ---
  125. -- Encodes a string to Base64.
  126. -- @param bdata Data to be encoded.
  127. -- @return Base64-encoded string.
  128. function enc(bdata)
  129.     local pos = 1
  130.     local byte
  131.     local nbyte = ''
  132.     -- local nbuffer = {}
  133.     local b64dataBuf = {}
  134.     while pos <= #bdata  do
  135.         pos, byte = bunpack("B1", bdata, pos)
  136.         nbyte = nbyte .. byte
  137.         append(b64dataBuf, b64enc6bit(substr(nbyte, 1, 6)))
  138.         nbyte = substr(nbyte,7)
  139.         if (#nbyte == 6) then
  140.             append(b64dataBuf, b64enc6bit(nbyte))
  141.             nbyte = ''
  142.         end
  143.     end
  144.     if #nbyte == 2 then
  145.         append(b64dataBuf, b64enc6bit(nbyte .. "0000") ) 
  146.         append(b64dataBuf, "==")
  147.     elseif #nbyte == 4 then
  148.         append(b64dataBuf, b64enc6bit(nbyte .. "00"))
  149.         append(b64dataBuf, '=')
  150.     end
  151.     return concat(b64dataBuf)
  152. end
  153.  
  154.  
  155. ---
  156. -- Decodes Base64-encoded data.
  157. -- @param b64data Base64 encoded data.
  158. -- @return Decoded data.
  159. function dec(b64data)
  160.     local bdataBuf = {}
  161.     local pos = 1
  162.     local byte
  163.     local nbyte = ''
  164.     for pos = 1, #b64data do -- while pos <= string.len(b64data) do
  165.         byte = b64dec6bit(substr(b64data, pos, pos))
  166.         if not byte then return end
  167.         nbyte = nbyte .. byte
  168.         if #nbyte >= 8 then
  169.             append(bdataBuf, bpack("B", substr(nbyte, 1, 8)))
  170.             nbyte = substr(nbyte, 9)
  171.         end
  172. --        pos = pos + 1
  173.     end
  174.     return concat(bdataBuf)
  175. end
  176.  
  177.