[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Speed optimized base64 encoder for Lua 5.3
- From: Ico Doornekamp <lua@...>
- Date: Tue, 04 Nov 2014 14:39:23 +0100
I wrote the snippet below today to speed up the base64 encoding in my
application using the new binary operators in Lua5.3, it might be of use for
others. I think the algorithm is pretty much optimal, but I'm open to any
suggestions and improvements.
Every three input bytes are mapped to four output bytes using the binary
operations below:
a b c
+-----------------+-----------------+-----------------+
| 0 0 0 0 0 0 1 1 | 1 1 1 1 2 2 2 2 | 2 2 3 3 3 3 3 3 |
+|- - - - - -|- - + - - - -|- - - - + - -|- - - - - -|+
/ / | \ \
/ / | \ \
a>>2 (a&3)<<4|b>>4 (b&15)<<2|c>>6 c&63
The input is padded to always be a multiple of three bytes, the output padding
with '='s is fixed up after calculating the base64 of the padded input string.
local bs = { [0] =
'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','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','0','1','2','3','4','5','6','7','8','9','+','/',
}
local function base64(s)
local byte, rep = string.byte, string.rep
local pad = 2 - ((#s-1) % 3)
s = (s..rep('\0', pad)):gsub("...", function(cs)
local a, b, c = byte(cs, 1, 3)
return bs[a>>2] .. bs[(a&3)<<4|b>>4] .. bs[(b&15)<<2|c>>6] .. bs[c&63]
end)
return s:sub(1, #s-pad) .. rep('=', pad)
end
assert(base64("") == "")
assert(base64("f") == "Zg==")
assert(base64("fo") == "Zm8=")
assert(base64("foo") == "Zm9v")
assert(base64("foob") == "Zm9vYg==")
assert(base64("fooba") == "Zm9vYmE=")
assert(base64("foobar") == "Zm9vYmFy")
--
:wq
^X^Cy^K^X^C^C^C^C