--- -- Base32 encoding and decoding. Follows RFC 4648. -- -- @author Philip Pickering -- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html -- @ported base64 to base32 -- thanks to Patrick Donnelly for some optimizations --module(... or "base32",package.seeall) -- local bin = require 'bin' -- local stdnse = require 'stdnse' -- _ENV = stdnse.module("base32", stdnse.seeall) local bin = require "bin" local stdnse = require "stdnse" local string = require "string" local table = require "table" _ENV = stdnse.module("base32", stdnse.seeall) -- todo: make metatable/index --> '' for b32dctable local b32standard = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', } local b32dcstandard = {} -- efficency b32dcstandard['A'] = '00000' b32dcstandard['B'] = '00001' b32dcstandard['C'] = '00010' b32dcstandard['D'] = '00011' b32dcstandard['E'] = '00100' b32dcstandard['F'] = '00101' b32dcstandard['G'] = '00110' b32dcstandard['H'] = '00111' b32dcstandard['I'] = '01000' b32dcstandard['J'] = '01001' b32dcstandard['K'] = '01010' b32dcstandard['L'] = '01011' b32dcstandard['M'] = '01100' b32dcstandard['N'] = '01101' b32dcstandard['O'] = '01110' b32dcstandard['P'] = '01111' b32dcstandard['Q'] = '10000' b32dcstandard['R'] = '10001' b32dcstandard['S'] = '10010' b32dcstandard['T'] = '10011' b32dcstandard['U'] = '10100' b32dcstandard['V'] = '10101' b32dcstandard['W'] = '10110' b32dcstandard['X'] = '10111' b32dcstandard['Y'] = '11000' b32dcstandard['Z'] = '11001' b32dcstandard['2'] = '11010' b32dcstandard['3'] = '11011' b32dcstandard['4'] = '11100' b32dcstandard['5'] = '11101' b32dcstandard['6'] = '11110' b32dcstandard['7'] = '11111' local b32hexExtend = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', } local b32dchexExtend = {} -- efficency b32dchexExtend['0'] = '00000' b32dchexExtend['1'] = '00001' b32dchexExtend['2'] = '00010' b32dchexExtend['3'] = '00011' b32dchexExtend['4'] = '00100' b32dchexExtend['5'] = '00101' b32dchexExtend['6'] = '00110' b32dchexExtend['7'] = '00111' b32dchexExtend['8'] = '01000' b32dchexExtend['9'] = '01001' b32dchexExtend['A'] = '01010' b32dchexExtend['B'] = '01011' b32dchexExtend['C'] = '01100' b32dchexExtend['D'] = '01101' b32dchexExtend['E'] = '01110' b32dchexExtend['F'] = '01111' b32dchexExtend['G'] = '10000' b32dchexExtend['H'] = '10001' b32dchexExtend['I'] = '10010' b32dchexExtend['J'] = '10011' b32dchexExtend['K'] = '10100' b32dchexExtend['L'] = '10101' b32dchexExtend['M'] = '10110' b32dchexExtend['N'] = '10111' b32dchexExtend['O'] = '11000' b32dchexExtend['P'] = '11001' b32dchexExtend['Q'] = '11010' b32dchexExtend['R'] = '11011' b32dchexExtend['S'] = '11100' b32dchexExtend['T'] = '11101' b32dchexExtend['U'] = '11110' b32dchexExtend['V'] = '11111' local b32table = b32standard local b32dctable = b32dcstandard local append = table.insert local substr = string.sub local bpack = bin.pack local bunpack = bin.unpack local concat = table.concat --- -- Encode bits to a Base32-encoded character. -- @param bits String of five bits to be encoded. -- @return Encoded character. local function b32enc5bit(bits) local byte = tonumber(bits, 2) + 1 return b32table[byte] end --- -- Decodes a Base32-encoded character into a string of binary digits. -- @param b32byte A single base32-encoded character. -- @return String of five decoded bits. local function b32dec5bit(b32byte) local bits = b32dctable[b32byte] if bits then return bits end return '' end --- -- Encodes a string to Base32. -- @param bdata Data to be encoded. -- @param hexExtend pass true to use the hex extended char set -- @return Base32-encoded string. function enc(bdata, hexExtend) local _, bitstring = bunpack(">B".. #bdata,bdata) local b32dataBuf = {} if hexExtend then b32table = b32hexExtend b32dctable = b32dchexExtend end while #bitstring > 4 do append(b32dataBuf,b32enc5bit(substr(bitstring,1,5))) bitstring = substr(bitstring,6) end if #bitstring == 1 then append(b32dataBuf, b32enc5bit(bitstring .. "0000")) append(b32dataBuf, '====') elseif #bitstring == 2 then append(b32dataBuf, b32enc5bit(bitstring .. "000") ) append(b32dataBuf, '=') elseif #bitstring == 3 then append(b32dataBuf, b32enc5bit(bitstring .. "00") ) append(b32dataBuf, "======") elseif #bitstring == 4 then append(b32dataBuf, b32enc5bit(bitstring .. "0") ) append(b32dataBuf, '===') end return concat(b32dataBuf) end --- -- Decodes Base32-encoded data. -- @param b32data Base32 encoded data. -- @param hexExtend pass true to use the hex extended char set -- @return Decoded data. function dec(b32data, hexExtend) local bdataBuf = {} local pos = 1 local byte local nbyte = '' if hexExtend then b32table = b32hexExtend b32dctable = b32dchexExtend end for pos = 1, #b32data do -- while pos <= string.len(b32data) do byte = b32dec5bit(substr(b32data, pos, pos)) if not byte then return end nbyte = nbyte .. byte if #nbyte >= 8 then append(bdataBuf, bpack("B", substr(nbyte, 1, 8))) nbyte = substr(nbyte, 9) end -- pos = pos + 1 end return concat(bdataBuf) end return _ENV;