---
-- Base32 encoding and decoding. Follows RFC 4648.
--
-- @author Philip Pickering <pgpickering@gmail.com>
-- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
-- @ported base64 to base32 <john.r.bond@gmail.com>
-- 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;
@KyuuKazami