Picture of Brian Love wearing black against a dark wall in Portland, OR.

Brian Love

Hash Any ColdFusion Type

In order to generate a unique identifier for caching an object I needed to create a function to accept any data type, and to return a unique hash from that object. I thought this was a pretty useful function, so I thought I would share it here.

The use case for this function is to generatethe id for caching a query. I am using the cacheregion and cacheid attributes for a <cfquery> tag.

<cfquery datasource="#getDatasource()#" name="local.q" cacheregion="#region.getRegion()#" cacheid="#region.getId()#">
  ....
</cfquery>

I simply have a Region object that has to methods:

In the getId() method I need to generate a unique identifier. To do this the Region object needed to be able to create a unique ID (or hash) from any variable.

Data Types

Here are the data types that I am serializing or hashing:

Hashify()

Here is the final code for my hashify() function. If you pass any object to the hashify() function you will get an MD5 hash of that object.

private string function hashify(required any value) {
  //return an empty string for null
  if (IsNull(arguments.value)) {
    return "";
  }

  //return a simple value
  if (IsSimpleValue(arguments.value)) {
    return Hash(arguments.value, "MD5");
  }

  //return binary value in Base64
  if (IsBinary(arguments.value)) {
    return hashify(value=ToBase64(arguments.value));
  }

  //serialize ColdFusion objects
  if (IsObject(arguments.value)) {
    return hashify(value=ObjectSave(arguments.value));
  }

  //struct
  if (IsStruct(arguments.value)) {
    var values = "";
    for (var key in arguments.value) {
      values &= hashify(value=key) & hashify(value=arguments.value[key]);
    }
    return hashify(value=values);
  }

  //array
  if (IsArray(arguments.value)) {
    var values = "";
    for(var i=ArrayLen(arguments.value); i > 0; i--){
      values &= hashify(value=i) & hashify(value=arguments.value[i]);
    }
    return hashify(value=values);
  }

  //query
  if (IsQuery(arguments.value)) {
    return hashify(value=ObjectSave(arguments.value));
  }
}