# 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.

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'}
};
``````