Monthly Archive for October, 2005

cfusion_encrypt/cfusion_decrypt UDFs

I was using cfusion_encrypt and cfusion_decrypt
today, and decided that even though they don't appear to be going
anywhere, they might at some point, and dealing with it shouldn't be a
big deal. I'm also pretty sure that BD doesn't have the
functions. So I thought why not write my own?

<cffunction name="fusion_encrypt" output="false" returntype="string">
  <cfargument name="string" type="string" required="true" />
  <cfargument name="key" type="string" required="true" />
  <cfset var i = "" />
  <cfset var result = "" />
  <cfset key = repeatString(key, ceiling(len(string) / len(key))) />
  <cfloop from="1" to="#len(string)#" index="i">
    <cfset result = result & rJustify(formatBaseN(binaryXOR(asc(mid(string, i, 1)), asc(mid(key, i, 1))), 16), 2) />
  </cfloop>
  <cfreturn replace(result, " ", "0", "all") />
</cffunction>
<cffunction name="fusion_decrypt" output="false" returntype="string">
  <cfargument name="string" type="string" required="true" />
  <cfargument name="key" type="string" required="true" />
  <cfset var i = "" />
  <cfset var result = "" />
  <cfset key = repeatString(key, ceiling(len(string) / 2 / len(key))) />
  <cfloop from="2" to="#len(string)#" index="i" step="2">
    <cfset result = result & chr(binaryXOR(inputBaseN(mid(string, i - 1, 2), 16), asc(mid(key, i / 2, 1)))) />
  </cfloop>
  <cfreturn result />
</cffunction>
<cffunction name="binaryXOR" output="false" returntype="numeric">
  <cfargument name="n1" type="numeric" required="true" />
  <cfargument name="n2" type="numeric" required="true" />
  <cfset n1 = formatBaseN(n1, 2) />
  <cfset n2 = formatBaseN(n2, 2) />
  <cfreturn inputBaseN(replace(n1 + n2, 2, 0, "all"), 2) />
</cffunction>

The binaryXOR is a requirement for both functions, but
it could easily be inlined out of existance if the extra UDF is a
problem. Here's some code to illustrating:

<cfset key = "test" />
<cfoutput>
<table>
<cfloop list="barney,is,damn cool!" index="i">
  <tr>
    <td>#i#</td>
    <td>#cfusion_encrypt(i, key)#</td>
    <td>#fusion_encrypt(i, key)#</td>
    <td>#cfusion_decrypt(cfusion_encrypt(i, key), key)#</td>
    <td>#fusion_decrypt(fusion_encrypt(i, key), key)#</td>
  </tr>
</cfloop>
</table>
</cfoutput>

I'm Back!

Much thanks to Bob Clingan, who pointed out a seemingly unrelated
setting in GMail, my email woes seem to have vanished.  The
culprit was choosing UTF-8 as my outgoing mail encoding, rather than
'default' (which is ISO-8859-1 for me).  Of course, the charset
has nothing to do with the problem, but Google decided UTF-8 messages
should be sent base-64 encoded, while 'default' messages go in plain
text.  No idea why, but fortunately my issue seems to be solved,
as long as I don't need to send any non-latin-1 characters in my email.

Thanks
to everyone who helped me in troubleshooting the issue over the past
few days, and especially to Bob who came up with solution (even though
it was backwards).

HoF Hates Base-64

After some careful observation this morning, it appears that email I
sent do HoF mailing lists is being killed outright.  So basically
I'm cut off form the CF world until I either decide to change my email
address, GMail gets off their ass an switches Base-64 encoding back
off, or everyone fixes their mailing software.

I haven't decided the best way to handle this yet.  But for now, I'll probably just be silent.

More Blank Message Info

After another day of fighting the blank message demons, I've assembled some more information.  On October 1st, Gmail
started using the Base-64 transfer encoding on messages I sent.  I
sent two messages to CFCDev on the 6th, and then it wasn't until the 13th
(when the problem first came to my attention) that I sent any other
messages to that list.  I believe this explains how the problem
went from it's initial cause to where we are today with such a long
delay.  As I said before, the HoF lists don't have this issue,
because they're not going through a listserv, but rather a CF
application.

Interestingly, GMail doesn't seem to be using Base-64 for all
it's sent messages; only those for certain accounts go out with that
encoding.  I checked the sent mail from another account and it is
still sending messages with quoted-printable encoding.  I'd be
interested to know if any other people are sending with Base-64 from
their accounts ('show original' on one of your sent messages).

A couple posts on the BD-interest mailing list revealed the same
issues as on CFCDev.  This confirms (or at least provides heavy
support for it) my suspicion that misbehaving mailing list software is
where the problem resides.  The BD-interest list is using IMail
from IPSwitch, though an older version.  When Ray gets back from
MAX we'll see if he's using the same thing for CFCDev.

'Blank Barney Messages'

Over the past couple days, there have been numerous complaints about
my messages showing up blank in various people's inboxes, and I'm
trying to nail down why.  Here's what I suspect has happened:

GMail
started (at some unknown point) sending messages with a base-64 content
transfer encoding.  Mailing list software often appends a footer to
the bottom of the message, and when that footer is textually appended
to a base-64 encoded message, the result is an invalid message. 
The proper method would be to decode the base-64 message, add the
footer, and then optionally reencode it.  Once you receive such an
invalid message, some client appear to be able to read it, and others
just render a blank message.

Supporting
this is the fact that no one has complained about email coming directly
from me, or via the House of Fusion lists (which don't actually use a
mailing list server).  So, if you receive a blank email from me
(or anyone else), please let me know, either by emailing me, or by
commenting on this post.  Please include your name, email, where
you got the message from (i.e. what mailing list), and what email
client you're using.  Hopefully with some more data, I can get
this problem nailed down, and see about getting fixed.

Thanks. 

ColdFusion and Batik

I've been using SVG for custom charting stuff for several years now,
and it's really nice. Only problem is that it requires an SVG
plugin, and it's not very common. No big deal for admin sites,
but for more public usage, that's pretty much a concept killer.

Enter Batik.

Batik is a Java SVG implementation by the Apache Group that, aside
from rendering SVG, has a lot of really neat supporting tools.
One of them is a group of transcoders that'll take an SVG file and turn
it into an image. Do that, and suddenly your SVG charts are
consumable by the general public. Obviously the transcoders don't
do the animation and scripting that SVG supports, but for charts,
that's no big deal.

Installation is a snap, though CF7 has a partial Batik package
included that needs to be moved out of the way first. Both
standalone and multiserver installs should have a WEB-INF/cfform/jars
directory with a few batik-*.jar files. Those need to be moved
away (I opted for putting them in a new WEB-INF/cfform/batik-jars
directory), and then a full Batik package needs to be installed.
For standalone, I found $cfroot/lib to be optimal, and on multiserver
they should go in WEB-INF/lib.

Once done, all you need is a bit of magic like this:

<cfset svgPath = "test.svg" />
<cfset pngPath = "test.png" />
<cfset svgFile = expandPath(svgPath) />
<cfset pngFile = expandPath(pngPath) />
<cfset t = createObject("java", "org.apache.batik.transcoder.image.PNGTranscoder").init() />
<cfset svgURI = createObject("java", "java.io.File").init(svgFile).toURL().toString() />
<cfset input = createObject("java", "org.apache.batik.transcoder.TranscoderInput").init(svgURI) />
<cfset ostream = createObject("java", "java.io.FileOutputStream").init(pngFile) />
<cfset output = createObject("java", "org.apache.batik.transcoder.TranscoderOutput").init(ostream) />
<cfset t.transcode(input, output) />
<cfset ostream.flush() /> <cfset ostream.close() />

<cfoutput>
<embed src="#svgPath#" width="1024" height="265" type="image/svg+xml" />
<img src="#pngPath#" />
</cfoutput>

You will, of course, want to update the width and height on the
EMBED tag to match your file. I haven't tested any of this on
CF6, but it should be even simpler, since there doesn't appear to be
the partial Batik install that needs to be moved out of the way.

As near as I can tell, CF itself isn't any worse for wear with the updated
Batik, though I can't say I've tested very thoroughly.