[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: Speed optimized base64 encoder for Lua 5.3
- From: Thijs Schreijer <thijs@...>
- Date: Tue, 4 Nov 2014 16:47:38 +0000
Might be worthwhile to put up on the wiki, a more appropriate place even.
Thijs
> -----Original Message-----
> From: lua-l-bounces@lists.lua.org [mailto:lua-l-bounces@lists.lua.org] On
> Behalf Of Ico Doornekamp
> Sent: dinsdag 4 november 2014 14:39
> To: lua-l
> Subject: Speed optimized base64 encoder for Lua 5.3
>
> 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