In Salesforce development, generating unique identifiers is a common requirement. These identifiers, known as GUIDs (Globally Unique Identifiers) or UUIDs (Universally Unique Identifiers), are crucial for various purposes, such as:
This article explores different methods for generating GUIDs/UUIDs in Salesforce, offering a detailed look at Apex code solutions and considerations for choosing the right approach.
A GUID/UUID is a 128-bit number used to uniquely identify information in computer systems. The most common format, as requested in the original question, is a string of 32 hexadecimal digits, displayed in five groups separated by hyphens, in the form nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn
.
Several approaches exist for generating GUIDs/UUIDs in Salesforce Apex code. Let's examine some of the most popular and effective techniques:
As of Spring '24, Salesforce provides a built-in UUID
class, simplifying the process of generating random UUIDs (version 4). This is now the recommended and easiest approach.
UUID uuIdV4 = UUID.randomUUID();
String uuIdV4Str = uuIdV4.toString();
System.debug(uuIdV4Str); // Example: 92a43945-23ca-4039-8450-7bfb6ade156a
Benefits:
Considerations:
This method uses the Crypto
class to generate a 128-bit AES key and then converts it to a hexadecimal string. While it produces a GUID-like string, be aware that it might not strictly adhere to UUID standards.
Blob b = Crypto.GenerateAESKey(128);
String h = EncodingUtil.ConvertTohex(b);
String guid = h.SubString(0,8)+ '-' + h.SubString(8,12) + '-' + h.SubString(12,16) + '-' + h.SubString(16,20) + '-' + h.substring(20);
System.debug(guid);
Benefits:
Considerations:
This approach combines a custom GuidUtil
class with the Crypto.getRandomInteger()
method for generating cryptographically secure random numbers. This method adheres more closely to the UUID v4 standards.
public class GuidUtil {
private static String kHexChars = '0123456789abcdef';
global static String NewGuid() {
String returnValue = '';
Integer nextByte = 0;
for (Integer i=0; i<16; i++) {
if (i==4 || i==6 || i==8 || i==10) returnValue += '-';
nextByte = Crypto.getRandomInteger() mod 256; // Get a random byte (0-255)
if (i==6) {
nextByte = nextByte & 15;
nextByte = nextByte | (4 << 4); // Set version to 4
}
if (i==8) {
nextByte = nextByte & 63;
nextByte = nextByte | 128; // Set variant to RFC4122
}
returnValue += getCharAtIndex(kHexChars, nextByte >> 4);
returnValue += getCharAtIndex(kHexChars, nextByte & 15);
}
return returnValue;
}
global static String getCharAtIndex(String str, Integer index) {
if (str == null) return null;
if (str.length() <= 0) return str;
if (index == str.length()) return null;
return str.substring(index, index+1);
}
}
Explanation:
Crypto.getRandomInteger()
to generate random numbers, which are cryptographically secure.Benefits:
Crypto.getRandomInteger()
for better randomness.This solution provides a complete class and a test method for generating version 4 GUIDs. It follows the UUID v4 standards rigorously ensuring the generated IDs are compliant.
public class GuidUtil {
static List<String> hexMap = new List<String> { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static String NewGuid() {
String randomStringAsHex = EncodingUtil.ConvertTohex(Crypto.GenerateAESKey(128));
String versionHexBits = randomStringAsHex.SubString(14,16); // 7th byte
String variantHexBits = randomStringAsHex.SubString(18,20); // 9th byte
Integer versionIntBits = convertHexToInt(versionHexBits);
Integer variantIntBits = convertHexToInt(variantHexBits);
Integer versionShiftedIntBits = versionIntBits & 15 | 64; // (i & 0x0f) | 0x40
Integer variantShiftedIntBits = variantIntBits & 63 | 128; // (i & 0x3f) | 0x80
String versionShiftedHexBits = convertIntToHex(versionShiftedIntBits); // Always begins with 4
String variantShiftedHexBits = convertIntToHex(variantShiftedIntBits); // Always begins with one of 8,9,a,b
String guid = randomStringAsHex.SubString(0,8) + '-' + randomStringAsHex.SubString(8,12) + '-' + versionShiftedHexBits + randomStringAsHex.SubString(14,16) + '-' + variantShiftedHexBits + randomStringAsHex.SubString(18,20) + '-' + randomStringAsHex.substring(20);
return guid;
}
static Integer convertHexToInt(String hex) {
Integer d0 = hexMap.IndexOf(hex.Substring(1,2));
Integer d1 = hexMap.IndexOf(hex.Substring(0,1));
Integer intval = d0 + (d1*16);
return intval;
}
static String convertIntToHex(Integer intval) {
String hs0 = hexMap.Get(intval & 15); // i & 0x0f
String hs1 = hexMap.Get(((intval >> 4) & 15)); //(i >> 4) & 0x0f
return hs1+hs0;
}
}
@isTest
public class GuidUtilSpec {
private static testmethod void GuidIsV4() {
Pattern p = Pattern.compile('[\\w]{8}-[\\w]{4}-4[\\w]{3}-[89ab][\\w]{3}-[\\w]{12}');
for(Integer x = 0; x < 100; x++) {
Matcher m = p.matcher(GuidUtil.NewGuid());
System.assert(m.matches() == true);
}
}
}
Key improvements:
UUID
class is the simplest and most reliable option.Crypto.getRandomInteger()
is sufficient to ensure uniqueness.GuidUtil
class with testing.Generating GUIDs/UUIDs in Salesforce is essential for maintaining data integrity and enabling seamless integration with other systems. While various methods exist, the built-in UUID
class introduced in Spring '24 offers the most straightforward and recommended solution. If you are on an older version or require strict adherence to the UUID v4 standard, the GuidUtil
class with Crypto.getRandomInteger()
provides a robust and secure alternative. By understanding the nuances of each approach, developers can choose the best method for their specific needs and ensure the uniqueness and reliability of their Salesforce applications.