ClarionX Updates

    follow me on Twitter

    Subscribe

    Enter your email address:

    Delivered by FeedBurner

    Blog powered by TypePad
    Member since 08/2006

    June 04, 2007

    Writing Base64

    We have seen how to decode base64 now lets see how to encode base64....

    This is pretty much a reverse of the decode function with a couple of exceptions. Then base64char function just does a lookup on a number for the corresponding character in the table.

    All we do is loop throuugh the raw string  data in groups of three obviously at the end if the source data is not a multiple of 3 we will buffer with the padding character ''=".

    With each group of three bytes (24 bits) we transform that into four 6 bit characters from our limited character set..

    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

    and the padding char =.

    Here is the code:

    Base64encode

          oString = ''
          BytesLeft# = LEN(CLIP(lString))
          LOOP i# = 1 TO LEN(CLIP(lString)) BY 3
            IF BytesLeft# = 1 THEN
            BigNumber# = BSHIFT(VAL(lString[i#]),16)
            Char1# = BAND(BSHIFT(BigNumber#,-18),111111b)
            Char2# = BAND(BSHIFT(BigNumber#,-12),111111b)
            oString = LEFT(CLIP(oString)) & base64char(Char1#)&base64char(Char2#)&'=='
            ELSIF BytesLeft# = 2 THEN
            BigNumber# = BSHIFT(VAL(lString[i#]),16) + BSHIFT(VAL(lString[i# + 1]),8)
            Char1# = BAND(BSHIFT(BigNumber#,-18),111111b)
            Char2# = BAND(BSHIFT(BigNumber#,-12),111111b)
            Char3# = BAND(BSHIFT(BigNumber#,-6),111111b)
            oString = LEFT(CLIP(oString)) & base64char(Char1#)&base64char(Char2#)&base64char(Char3#)&'='
            ELSE
            BigNumber# = BSHIFT(VAL(lString[i#]),16) + BSHIFT(VAL(lString[i# + 1]),8) + VAL(lString[i# + 2])
            Char1# = BAND(BSHIFT(BigNumber#,-18),111111b)
            Char2# = BAND(BSHIFT(BigNumber#,-12),111111b)
            Char3# = BAND(BSHIFT(BigNumber#,-6),111111b)
            Char4# = BAND(BigNumber#,111111b)
            oString = LEFT(CLIP(oString)) & base64char(Char1#)&base64char(Char2#)&base64char(Char3#)&base64char(Char4#)
            END
            IF BytesLeft# <= 3 THEN BREAK.
            BytesLeft# -= 3
          END
          RETURN LEFT(CLIP(oString))

    Enjoy....obvioulsy this code could be improved. Currenlty it is limited to 4Mb and it involves repeated clips of a large string....til next time

    May 29, 2007

    Reading Base64 ...

    This is the first article in an Internet Protocol/encoding Series...As developers we will at one time or another need to read base64 encoded data....heres my take...

    Base64 is used to encode binary files in a text format suitable to be encapsulated in text documents. One interesting thing about base 64 is that it is one of the only data representation
    schemes in modern use that doesn’t encrypt or compress the data. It just represents data
    in a different form.

    The solution to this problem was to create a data representation protocol that would allow
    binary data to be encapsulated within another document. The defacto standard for doing
    this is called base 64. In fact, some applications use base 64 as an encryption technique,
    albeit a weak one. Basic authentication over the Internet encrypts the username-password
    using base 64.

    Here is a simple base64 decoder algorithm that has been very useful over the years...

    base64decode PROCEDURE(STRING b64)

    b64chars STRING('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')

    oString ANY

    CODE

    oString = '' !Dont use CLEAR it will cause a GPF on an ANY Variable

    ! Base64 strings especially those from emails can contain carriage returns and tabs these must be removed before decoding....

    b64 = StringReplace(b64,CHR(9),'')
    b64 = StringReplace(b64,CHR(10),'')
    b64 = StringReplace(b64,CHR(13),'')

    ! Base64 strings are groups of four characters and need to be stepped through by 4....

    LOOP i# = 1 TO LEN(CLIP(b64)) BY 4

    !Create a 24 bit Number by bit shifting the four chars values by  6 bit segments...

    BigNumber# = BSHIFT(INSTRING(b64[i#],b64chars,1,1)-1,18) + BSHIFT(INSTRING(b64[i#+1],b64chars,1,1)-1,12) + BSHIFT(INSTRING(b64[i#+2],b64chars,1,1)-1,6) + (INSTRING(b64[i#+3],b64chars,1,1)-1)

    !Extract the original 3 ascii chars by bit shifting in the other direction by 8 bit segments...

    Char1# = BAND(BSHIFT(BigNumber#,-16),11111111b)
    Char2# = BAND(BSHIFT(BigNumber#,-8),11111111b)
    Char3# = BAND(BigNumber#,11111111b)

    !handle trailing padding characters thus...and translate the character values...
    IF b64[i#+3] = '=' AND b64[i#+2] ~= '=' THEN
    oString = oString & CHR(Char1#)&CHR(Char2#)
    ELSIF b64[i#+3] = '=' AND b64[i#+2] = '=' THEN
    oString = oString & CHR(Char1#)
    ELSE
    oString = oString & CHR(Char1#)&CHR(Char2#)&CHR(Char3#)
    END
    !repeat operation for each group of four base64 chars

    END

    RETURN CLIP(oString)

    The result is the unencoded text or binary data....for more info on base64 like a encoding checkout RFC 3548...