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

Print Preview

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.

Do I really care about this?

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

comments powered by Disqus

© El Toro . IT @ 2013
Andrés Pérez