How can I convert a 15 char Id value into an 18 char Id value?

What is the formula for calculating the additional 3 characters needed to append to a 15 char Id in order to form its equivalent 18 char Id?

I have a situation where I need to compare 15 char Ids (uploaded by users) with their 18 char equivalents (stored in a local database), and it would be most efficient if I could convert the 15 char Ids to 18 chars before comparing (The 18 char Ids are PK fields in my local database, and while I could compare using a like query clause, it would be more efficient to convert to 18 chars and perform lookups based on those values).

The base algorithm would be great – even better is an C# implementation.

Answer

Explanation of the algorithm: This is based on the algorithm given here. The example below is using a made up salesforce 15 char Id 001A000010khO8J

  1. Separate the 15 char Id into 3 groups of 5 chars. You now have 3 strings (the triplet variable below): 001A0, 00010 and khO8J
  2. Reverse each string. The three strings are now 0A100, 01000 and J8Ohk
  3. In each string, convert all Uppercase chars to 1, all other chars to 0. The three strings are now 01000, 00000 and 10100.
  4. Look up the corresponding char in the BinaryIdLookup based. This gives us a suffix of IAU.
  5. The 3 chars generated (in order) are appended to the 15 char Id value, giving you an 18 char Id value of 001A000010khO8JIAU.

I have created an implementation of this in C# and have tested this on a number of real Salesforce Ids and it seems to do the job. Code is in this gist or below:

static string Convert15CharTo18CharId(string id)
{
    if (string.IsNullOrEmpty(id)) throw new ArgumentNullException("id");
    if (id.Length == 18) return id;
    if (id.Length != 15) throw 
       new ArgumentException("Illegal argument length. 15 char string expected.", "id");

    var triplet = new List<string> { id.Substring(0, 5), 
                                     id.Substring(5, 5), 
                                     id.Substring(10, 5) };
    var str = new StringBuilder(5);
    var suffix = string.Empty;
    foreach (var value in triplet)
    {
        str.Clear();
        var reverse = value.Reverse().ToList();
        reverse.ForEach(c => str.Append(Char.IsUpper(c) ? "1" : "0"));
        suffix += BinaryIdLookup[str.ToString()];
    }
    return id + suffix;
}

static readonly Dictionary<string, char> BinaryIdLookup = new Dictionary<string, char>
{
    {"00000", 'A'}, {"00001", 'B'}, {"00010", 'C'}, {"00011", 'D'}, {"00100", 'E'},
    {"00101", 'F'}, {"00110", 'G'}, {"00111", 'H'}, {"01000", 'I'}, {"01001", 'J'},
    {"01010", 'K'}, {"01011", 'L'}, {"01100", 'M'}, {"01101", 'N'}, {"01110", 'O'}, 
    {"01111", 'P'}, {"10000", 'Q'}, {"10001", 'R'}, {"10010", 'S'}, {"10011", 'T'}, 
    {"10100", 'U'}, {"10101", 'V'}, {"10110", 'W'}, {"10111", 'X'}, {"11000", 'Y'}, 
    {"11001", 'Z'}, {"11010", '0'}, {"11011", '1'}, {"11100", '2'}, {"11101", '3'}, 
    {"11110", '4'}, {"11111", '5'}
};

Attribution
Source : Link , Question Author : Yaakov Ellis , Answer Author : Alex Tennant

Leave a Comment