Salesforce 15->18 digit GUID conversion in Ruby

Recently work has had me playing with Salesforce’s custom web services api. Web services are a powerful, and relatively under-used feature of salesforce that allows you to write your own soap(and now Rest) api methods. These are really handy when you need to, for instance, fetch all the accounts, cases, assets, opportunities etc. associated with a single contact. As powerful as they are, they are not without their own quirks (after all, this is Salesforce…)

The normal Salesforce soap api can accept as parameters either the standard, 15 digit, case sensitive GUID, or the 18 digit case insensitive API GUID. Unfortunately custom web servers are not so forgiving throwing apex errors when you pass in a 15 digit GUID. Our Ruby/Rails application needs to interact with this custom web service so I set out to understand how to calculate an 18 digit GUID from the 15 digit guid and implement the algorithm in Ruby. A quick google search shows the algorithm is already very well documented all over the web so I’m going to skip straight to the ruby implementation.

def convert_guid(short_guid)
    chunks = short_guid.chars.to_a
    char_map = %w{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5}
    extension = []
    chunks.each_slice(5) { |x| y = x.reverse.map {|c| (c.match /[A-Z]/) ? 1 : 0 }.join("").to_i(2) ; extension << y}
    short_guid + (extension.map {|e| char_map.at(e)}).join("").to_s
end

And now, the walk through:

  • Standard ruby definition for a method. This is not the line of code you’re looking for.
  • We need to convert our 15 character string to an array of characters, so we’ll do that by casting the string to an array of characters
  • The algorithm depends on doing a map lookup, so we need to define the map of characters we can possibly use to add to our guid.
  • Lets fire up an array to hold the characters we’re going to append to the 15digit guid.
  • Ok here’s the meat. Take our chunks array, and for each group of 5 digits execute the following block of code:
  • We calculate Y by reversing the 5 digits of this current chunk, (eg. 12345 becomes 54321) and execute the following block of code on each digit:
  • if the current digit is a regex match for a capital A-Z, replace it with a 1, otherwise replace the character with a 0.
  • Join the 5 1′s and 0′s we just calculated back into a single string using join.
  • Cast that 5 digit binary string to a binary integer.
  • Add the binary integer to the extension array we created in line 4.
  • Take the original short_guid, and add to it the results of the lookup map function. If the the number in 5.2 were, for instance, 5 we convert that 5, to the character “F” in the map (arrays, start with 0 remember?).
  • Finally, we force a cast to string and return!

Viola! an 18 digit, case insensitive Salesforce GUID suited for use as input parameters to your custom web services.

Leave a Reply

Your email address will not be published. Required fields are marked *