coldfusionbase64

How to add padding before decoding a base64 string?


ColdFusion's binaryDecode(input, 'base64') is picky because padding is mandatory.

What is the correct way to add padding with = to a base64 value?

1.) Ben Nadel uses:

value &= repeatString( "=", ( 4 - ( len( value ) % 4 ) ) );

2.) Arlo Carreon uses

<cfset res = Len(raw_str) % 4>
<cfif res eq 2>
     <cfset raw_str &= "==">
<cfelseif res eq 3>
     <cfset raw_str &= "=">
</cfif>

While they both seem to work, the 1st solution may return 1 to 4 ='s, while the 2nd solution may return 0, 1 or 2 ='s. Wikipedia on Base64 Padding seems to indicate that a valid base64 value should really have only 1 or 2 ='s.

1st solution seems to work with all base64 value lengths, but it may sometimes return 3 or 4 ='s which is kind of strange. Where as the 2nd solution may fail for base64 value that has remainder of 1. CF throws The input and output encodings are not same.


Solution

  • Padding is mandatory by specification (RFC 2045, 3548/4648).

    Implementations MUST include appropriate pad characters at the end of encoded data unless the specification referring to this document explicitly states otherwise.

    The correct way to fix missing padding is to append = until ( len(value) % 4 ) eq 0. This means a correctly padded Base64 string can only end:

    The specification allows ("may") ignoring excessive padding.

    If more than the allowed number of pad characters is found at the end of the string (e.g., a base 64 string terminated with "==="), the excess pad characters MAY also be ignored.


    Can you elaborate what you mean by The input and output encodings are not same.? This sounds like an invalid Base64 encoded string. You may want to check what toBinary() returns for the input. It will probably tell you The parameter 1 of function ToBinary, which is now ... must be a base-64 encoded string, which is exactly the problem.