Sunday, March 15, 2009

Convert 15-character Salesforce IDs to 18-characters IDs with Ruby



Algorithm:

Saleforce uses 15-character IDs as primary keys for every record.
When retrieving an ID over the API, 18-character case-insensitive IDs are returned.
Generally, this doesn't cause any problems because the 18-character version can be used anywhere the 15-character one is.
One problem arises though when you are storing IDs in a text field.
In this case, you may need to convert a 15-character ID into its 18-character version.

All case-sensitive ids are 15 chars.
To convert a 15 char case-sensitive id to an 18 char case-safe id follow these steps.
1. Divide the 15 char into 3 chunks of 5 chars each.
2. For each character give that position a value of 1 if uppercase, 0 otherwise (lowercase or number).
3. Combine the bits from each chunk into a 5 bit integer where the rightmost bit is the most significant bit. This will yield a number between 0 and 31 for each chunk.
4. Constuct an array that contains the sequence of capital letters A-Z and 0-5.
5. Use the integer from each chunk to choose a character from the array.
6. Append the resulting 3 characters, in chunk order, to the end of the 15 char id.


I used this code as example.


  1. def sf15to18(sf_id15)

  2. map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'

  3. extra = ''

  4. sf_id15.scan(/.{5}/).each do |chunk|

  5. bits = []

  6. chunk.scan(/.{1}/).each do |char|

  7. #Uppercase condition

  8. bits.unshift( (char.to_i == 0 && char != 0 && char.downcase != char) ? 1 : 0)

  9. end


  10. ind = bits.inject(0) do |ind, bit|

  11. ind + ind + bit

  12. end

  13. extra += map[ind..ind]

  14. end

  15. sf_id15 + extra

  16. end