base64_encode.ls
on base64_encode str
--
-- Base 64 encoding for director strings.
-- http://www.fourmilab.ch/webtools/base64/rfc1341.html
--
-- Cole Tierney -- <colet at putnamhill dot net>
--
--
-- Set up some constants.
--
-- set bit16Mask = integer( 255 + 255 * power(2,8) ) --== 65535
set bit16Mask = 65535 -- 00000000 00000000 11111111 11111111
set bit17mask = bit16Mask + 1 -- 00000000 00000001 00000000 00000000
-- set bit24Mask = integer( 255 + 255* power(2,8) + 255 * power(2,16) ) --== 16777215
set bit24Mask = 16777215 -- 00000000 11111111 11111111 11111111
set bit25Mask = bit24mask + 1 -- 00000001 00000000 00000000 00000000
set base64alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
set encodedStr = ""
set bit24grp = ""
repeat while length( str ) > 0
set ch = char 1 of str
delete char 1 of str
if length( bit24grp ) < 3 then -- Add the char to our group.
put ch after bit24grp
end if
if length( bit24grp ) = 3 then
-- If here, then we have a complete group of 24 bits (3 chars).
-- So extract our 4 six bit numbers, and add them to our encoded string.
-- First we'll turn it into an integer so we can perform our bitwise operations.
set c1 = charToNum( char 1 of bit24grp )
set c2 = charToNum( char 2 of bit24grp )
set c3 = charToNum( char 3 of bit24grp )
set int24bit = c3 + c2 * 256 + c1 * 65536 -- First byte will be high order.
repeat with i = 1 to 4 -- For each 6bit number (4 of them per group)...
set bit6Int = 0
repeat with j = 1 to 6 -- For each 6 bits...
set bit6Int = bit6Int * 2 -- First make room for another bit by shifting the 6 bit integer one place to the left.
set int24bit = int24bit * 2 -- Shift bits one place to the left.
set bit6Int = bitOr( bit6Int, bitAnd( int24bit, bit25Mask ) > 0 ) -- ...roll this bit into our 6 bit integer.
set int24bit = bitAnd( int24bit, bit24Mask ) -- Strip anything that landed in the 25th bit slot.
end repeat
-- Should now have our 6 bit base 64 index, so fetch our new character.
put char bit6Int + 1 of base64alphabet after encodedStr
end repeat
-- Start another 24 bit string
set bit24grp = ""
end if
end repeat
set bit6Int = 0
-- If current length of our 24 bit group string is non-zero then have an incomplete 24 bit group, so deal with it.
set bitGroupSize = length( bit24grp )
case bitGroupSize of
1: -- Have 8 bits left to encode:
-- Get the first 6 bits by shifting right twice (divide by 4).
set c1 = charToNum(char 1 of bit24grp)
set bit6int = c1
set bit6int = integer( bit6int / 4 )
put char bit6Int + 1 of base64alphabet after encodedStr
-- Get the last two bits by masking off the first 6 bits.
set bit6int = charToNum(char 1 of bit24grp)
set bit6int = bitAnd( c1, 3 )
-- Now shift left 4 times to make it 6 bits wide (double it 4 times).
set bit6int = bit6int * 16
put char bit6Int + 1 of base64alphabet after encodedStr
put "==" after encodedStr -- Finish off the 4 6bit group with the "=" pad char.
2: -- Have 16 bits (2 bytes) left to encode:
-- Get the first 6 bits by shifting right twice (divide by 4).
set c1 = charToNum(char 1 of bit24grp)
set c2 = charToNum(char 2 of bit24grp)
set bit16int = c2 + c1 * 256 -- First byte is high order.
repeat with i = 1 to 3
set bit6Int = 0
repeat with j = 1 to 6 -- For each 6 bits...
-- First make room for another bit by shifting resulting 6 bit integer one place to the left.
set bit6Int = bit6Int * 2
-- Start pealing bits off the left each time we shift left.
-- Shift bits one place to the left.
set bit16int = bit16int * 2
-- If a bit fell off the left end (bit 17 == 1), then add to our six bit number.
if bitAnd( bit16int, bit17Mask ) <> 0 then set bit6Int = bit6Int + 1
-- Strip anything that landed in the 17th bit slot.
set bit16int = bitAnd( bit16int, bit16Mask )
end repeat
-- Should now have our 6 bit base 64 index, so fetch our new character.
put char bit6Int + 1 of base64alphabet after encodedStr
end repeat
put "=" after encodedStr -- Finish off the 4 6bit group with the "=" pad char.
end case
return encodedStr
end