Converting A Base64 Value Back Into A String Using ColdFusion
Posted September 5, 2008 at 2:54 PM by Ben Nadel
This might seem super obvious to some of you, but this small problem had me stumped for a good 10 minutes this morning. I had an XML value that I was converting to Base64 for an HTTP post. Then, on the other side, I needed to take that Base64 encoded value and convert it back to a regular string for use with XML parsing. And then it hit, I had no idea how to, in ColdFusion, take a Base64 encoded value and convert it back to the original string.
Once I figured it out, it was laughably simple:
- <!--- Create a string value. --->
- <cfset strValue = "Hey there cutie patootie." />
- <!--- Convert to base 64. --->
- <cfset strBase64Value = ToBase64( strValue ) />
- To convert the base 64 value back to string, simply convert
- the it a binary representation and then back into to a string.
- <cfset strNewValue = ToString( ToBinary( strBase64Value ) ) />
- <!--- Output test data. --->
- Base 64: #strBase64Value#<br />
- Value: #strNewValue#
Running the above code, we get the following output:
Base 64: SGV5IHRoZXJlIGN1dGllIHBhdG9vdGllLg==
Value: Hey there cutie patootie.
In ColdFusion, the ToBinary() function takes a Base64 encoded value and converts it to its binary representation. This, of course, is a Byte Array. In our example, where each character of a string is represented by a single byte, we have one character per byte array index. Then, calling ToString() on that Byte Array simply converts that character-based byte array back into its string representation.
What Other People Are Searching For
[ local search ]
convert to base64 in coldfusion
[ local search ] decode base64 value in coldfusion
[ local search ] how to decode a base64 value in coldfusion
[ local search ] convert base64 value to string in coldfusion
I've done something similar in a MS SQL Server database - take a text field and output as string:
CAST(CAST(textField AS VARBINARY(1000)) AS VARCHAR(1000))
I think that's how it worked. I'm fairly sure most DBMSs have similar functions.
Earlier this week, I had to do the same thing except that the strValue was a GUID (hex). I found that converting the GUID to decimal and then trying to run ToBase64 on the resulting HUGE number resulted in a CF error. Apparently ToBase64 can only handle decimals up to a certain size. I did find the solution though (with Ray's help) and posted it here: http://www.coldfusionjedi.com/forums/messages.cfm?threadid=2E1AFB13-19B9-E658-9DEC415EB6931B97
Just FYI Ben. The CFML Reference manual is your friend. It's on page 1228.
Good to know.
I assume you needed to go to a decimal first for some reason; otherwise, you can convert any string to Base64 regardless of length.
It's funny, I have gone from String -> Base64 -> Binary so many times that I totally blanked on going the reverse order.
ps. I love the CFML Reference guide :)
Yes. Per my post on coldfusionjedi.com, I needed a *shorter* version of the GUID. If you treat it as a (hex) number, the resulting Base64 has fewer characters/digits than the original:
If you treat the GUID as a string, the resulting Base64 has more characters/digits than the original:
I discovered this phenomenon on Wikipedia, of all places, "When printing fewer characters is desired, GUIDs are sometimes encoded into a base64 or Ascii85 string. Base64-encoded GUID consists of 22 to 24 characters (depending on padding)."
Ahh, yes, that makes sense. Thanks for the clarification.
@John, thanks the hex tip. One thing I've found is the GUIDs are coming back with some 0's missing. Did you notice this?
GUID before: 3D0F1C1C-E3F6-11D3-896A-00105A7027AA
"GUID" after: 3DF1C1CE-3F61-1D38-96A0-105A7027AA
@Jason No, I either didn't notice that or didn't have that problem and, since Sep 2008, my need for this bit of logic went away and the code in question is not easily accessible. Perhaps you can share your code?
@John, It's your original code, I copy/pasted and used it for testing. No biggie, just wondering if it did the same for you. Thx
@Jason My bad. Right there it is at http://www.coldfusionjedi.com/forums/messages.cfm?threadid=2E1AFB13-19B9-E658-9DEC415EB6931B97 No, I didn't notice what you're describing. I was using ACF8. You?
@John, should be the same as yours unless my CF default is somehow different.
@Jason Try these and let me know. I think I might have fixed it and forgotten to update post on Ray's site. If this works, let me know and I will...
<cffunction access="public" name="HexToBase64" output="yes" returntype="string">
<cfargument name="Hex" type="string" required="yes">
<cfset Hex = Replace(Hex, "-", "", "ALL")>
<cfset outStream = CreateObject("java", "java.io.ByteArrayOutputStream").init()>
<cfset inputLength = Len(Hex)>
<cfset outputString = "">
<cfset i = 0>
<cfset ch = "">
<cfif inputLength mod 2 neq 0>
<cfset Hex = "0" & Hex>
<cfloop from="1" to="#inputLength#" index="i" step="2">
<cfset ch = Mid(Hex, i, 2)>
<cfset outStream.write(javacast("int", InputBaseN(ch, 16)))>
<cffunction access="public" name="Base64ToHex" output="yes" returntype="string">
<cfargument name="Base64" type="string" required="yes">
<cfset aBinary = ToBinary(Base64)>
<cfset Hex = "">
<cfloop index="i" from="1" to="#ArrayLen(aBinary)#">
<cfset Hex = Hex & Replace(RJustify(FormatBaseN(BitAnd(aBinary[i], 255), 16), 2), " ", "0", "ALL")>
<cfset Hex = Insert("-", Hex, 20)>
<cfset Hex = Insert("-", Hex, 16)>
<cfset Hex = Insert("-", Hex, 12)>
<cfset Hex = Insert("-", Hex, 8)>
@John, that worked, thanks for the update!
@Jason You're welcome!