How do I convert an ID from 15 to 18 characters? - El Toro - Find articles about Visualforce, Apex, Force.com and Salesforce in general How do I convert an ID from 15 to 18 characters?

Two versions of the same ID?

When a user pulls information containing the id from the API, the id contains 18 characters. On the other hand, if the user looks at the id in the Reports tab or the Weekly Export Service, the id will only contain 15 characters.

Can I get a 18 character ID from a 15? The above image was taken from Alan Shanahan blog

To convert a 15 char case-sensitive id to an 18 char case-safe id follow these steps:

1. Split the 15 char into 3 chunks of 5 chars each.

2. Reverse the chunks

3. For each character give that position a value of 1 if uppercase, 0 otherwise (lowercase or number).

4. Now convert from those bits to a character using a lookup table.

5. Append the resulting 3 characters, in chunk order, to the end of the 15 char id.

Both 15 and 18 character IDs are case sensitive inside Salesforce!

So why bother?

Salesforce provides case-sensitive and case-insensitive versions of the same globally unique id, because some external applications ignore case sensitivity when comparing strings. So, when working with external tools it is better to work with the 18 digits ID!

For example, VLOOKUP() in Excel are case insensitive. If you are looking for 00a000000a12345 using VLOOKUP(), you will find these records: 00a000000A12345 and 00a000000a12345.

Before you start coding this algorithm, check Google since there are many tools that allow you to convert from 15 to 18 character IDs

I have written this implementation of the algorithm in VB to convert an ID from 15 characters to 18 characters.

```Option Explicit

Public Function FixedSFID(inputID As String) As String
' If inputID has 18 characters, there is no need to convert it.
If Len(inputID) = 18 Then
FixedSFID = inputID
Exit Function
End If

' If inputID is not 15 characters long, must abort.
If Len(inputID) <> 15 Then
FixedSFID = "#VALUE!"
Exit Function
End If

' Now find the last 3 characters.
Dim table As String
Dim posID As Long
Dim binValue As Integer
table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"

' Reset binary value
binValue = 0

' The chunks are reversed in the algorithm, so count down.
For posID = 15 To 1 Step -1

' Update the binary value (Hint: Multiplying by 2)
binValue = (2 * binValue) + isUpperCase(Mid(inputID, posID, 1))

' Every 5th character, search in the table
If posID Mod 5 = 1 Then

' Look up in the "table", and prepend value
FixedSFID = Mid(table, binValue + 1, 1) + FixedSFID

' Reset binary value
binValue = 0

End If
Next posID

' Prepend value
FixedSFID = inputID + FixedSFID

End Function
Private Function isUpperCase(inChar As String) As Integer
' Number, return 0
If (IsNumeric(inChar)) Then
isUpperCase = 0
Exit Function
End If

' Lowercase, return 0
If (Asc(inChar) >= 97) And (Asc(inChar) <= 122) Then
isUpperCase = 0
Exit Function
End If

' Uppercase, return 1
If (Asc(inChar) >= 65) And (Asc(inChar) <= 90) Then
isUpperCase = 1
Exit Function
End If

isUpperCase = "ERROR"
End Function```

This is the PHP version of the code that one of my students recently sent me (Thanks, Bryan)

```To call it, you would simply go: \$myId = convertToAPIId(\$myShortenedId);

// Convert 15 digit ID to 18 digit ID
function convertToAPIId(\$value) {
if (strlen(\$value) == 15) {
// Separate blocks into 3 chunks of 5
\$block1 = substr(\$value, 0, 5);
\$block2 = substr(\$value, 5, 5);
\$block3 = substr(\$value, 10, 5);
// Reverse the strings
\$block1 = strrev(\$block1);
\$block2 = strrev(\$block2);
\$block3 = strrev(\$block3);
// Replace lowercase characters and numbers with 0, uppercase characters with 1
\$block1 = preg_replace('/([a-z]|[0-9])/', '0', \$block1);
\$block2 = preg_replace('/([a-z]|[0-9])/', '0', \$block2);
\$block3 = preg_replace('/([a-z]|[0-9])/', '0', \$block3);
\$block1 = preg_replace('/([A-Z])/', '1', \$block1);
\$block2 = preg_replace('/([A-Z])/', '1', \$block2);
\$block3 = preg_replace('/([A-Z])/', '1', \$block3);
// Run against lookup table to get corresponding character
\$block1 = \$this->convertAPIIdToLookup(\$block1);
\$block2 = \$this->convertAPIIdToLookup(\$block2);
\$block3 = \$this->convertAPIIdToLookup(\$block3);
return \$value . \$block1 . \$block2 . \$block3;
} else return \$value;
}

// Convert Salesforce API Id to lookup value
function convertAPIIdToLookup(\$value) {
\$convertedValue = '';
switch (\$value) {
case '00000':
\$convertedValue = 'A';
break;
case '00001':
\$convertedValue = 'B';
break;
case '00010':
\$convertedValue = 'C';
break;
case '00011':
\$convertedValue = 'D';
break;
case '00100':
\$convertedValue = 'E';
break;
case '00101':
\$convertedValue = 'F';
break;
case '00110':
\$convertedValue = 'G';
break;
case '00111':
\$convertedValue = 'H';
break;
case '01000':
\$convertedValue = 'I';
break;
case '01001':
\$convertedValue = 'J';
break;
case '01010':
\$convertedValue = 'K';
break;
case '01011':
\$convertedValue = 'L';
break;
case '01100':
\$convertedValue = 'M';
break;
case '01101':
\$convertedValue = 'N';
break;
case '01110':
\$convertedValue = 'O';
break;
case '01111':
\$convertedValue = 'P';
break;
case '10000':
\$convertedValue = 'Q';
break;
case '10001':
\$convertedValue = 'R';
break;
case '10010':
\$convertedValue = 'S';
break;
case '10011':
\$convertedValue = 'T';
break;
case '10100':
\$convertedValue = 'U';
break;
case '10101':
\$convertedValue = 'V';
break;
case '10110':
\$convertedValue = 'W';
break;
case '10111':
\$convertedValue = 'X';
break;
case '11000':
\$convertedValue = 'Y';
break;
case '11001':
\$convertedValue = 'Z';
break;
case '11010':
\$convertedValue = '0';
break;
case '11011':
\$convertedValue = '1';
break;
case '11100':
\$convertedValue = '2';
break;
case '11101':
\$convertedValue = '3';
break;
case '11110':
\$convertedValue = '4';
break;
case '11111':
\$convertedValue = '5';
break;
}
return \$convertedValue;
}```