Unique identifiers are essential in software development for ensuring data integrity and system scalability. Among these, the Globally Unique Identifier (GUID), also known as Universally Unique Identifier (UUID), stands out for its statistical uniqueness across space and time. This article delves into how to Get Random Guids, specifically focusing on Version 4 UUIDs, which rely on cryptographically secure random numbers.
Understanding GUIDs and UUID Version 4
A GUID (or UUID) is a 128-bit number used to uniquely identify information in computer systems. The Version 4 UUID is particularly significant because it utilizes a random number generation algorithm. This randomness is crucial for distributed systems where generating identifiers without central coordination is necessary.
Version 4 UUIDs are created using a cryptographically secure random number generator. The structure of a Version 4 UUID is defined by specific rules to ensure its format and distinguish it from other UUID versions. These rules involve setting certain bits to predefined values to indicate the version and variant.
Key characteristics of UUID Version 4:
- Randomness: Generated using high-quality random numbers, minimizing the chance of collision (two identical IDs).
- Decentralization: Can be generated independently without needing a central authority.
- Standard Format: Adheres to a specific format (xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where ‘y’ is one of 8, 9, A, or B), making them easily recognizable and parsable.
Generating a Random GUID (UUID v4)
To get a random GUID that conforms to the UUID Version 4 standard, follow these steps, as implemented in the Apex code example below:
- Generate 128 Random Bits: Start by creating 128 bits of cryptographically secure random data. This forms the basis of your UUID.
- Set the Version: Modify the 7th byte (byte index 6, zero-based) of the 128-bit random data to indicate Version 4. This is done by performing a bitwise AND operation with
0x0f
(to clear the 4 version bits) and then a bitwise OR operation with0x40
(to set the version bits to 0100, representing version 4). - Set the Variant: Adjust the 9th byte (byte index 8) to specify the UUID variant (variant 1 as per RFC 4122). Perform a bitwise AND with
0x3f
and then a bitwise OR with0x80
. This ensures compatibility and interoperability. - Convert to Hex and Format: Convert the 128 bits (16 bytes) into a 32-character hexadecimal string. Then, insert hyphens to separate sections of the UUID, resulting in the standard 8-4-4-4-12 format.
Apex Code Example: GuidUtil
Class
The following Apex class, GuidUtil
, demonstrates how to get a random GUID adhering to UUID Version 4 standards within the Salesforce platform.
```java
/* How to generate a version 4 GUID (random) 1. Generate 128 random bits 2. Set the version: Take the 7th byte perform an AND operation with 0x0f followed by an OR operation of 0x40. 3. Set the variant: Take the 9th byte perform an AND operation with 0x3f followed by an OR operation of 0x80. 4. Convert the data to hex and add dashes */ 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 bit String variantHexBits = randomStringAsHex.SubString(18,20); // 9th bit 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) { // https://stackoverflow.com/a/13465128 String hs0 = hexMap.Get(intval & 15); // i & 0x0f String hs1 = hexMap.Get(((intval >> 4) & 15)); //(i >> 4) & 0x0f return hs1+hs0; } }
Code Explanation:
NewGuid()
Method: This is the core method to get a random GUID.Crypto.GenerateAESKey(128)
: Generates 128 bits of cryptographically strong random data using AES key generation, ensuring a high level of randomness and security.EncodingUtil.ConvertTohex()
: Converts the random byte array into a hexadecimal string representation.- Version and Variant Bit Manipulation: The code carefully extracts and modifies specific bits to comply with the UUID Version 4 and variant specifications, as described in steps 2 and 3 above.
- Formatting: Hyphens are inserted at the correct positions to produce the standard UUID format.
convertHexToInt()
andconvertIntToHex()
Methods: These helper methods facilitate the conversion between hexadecimal string representations and integer values, used in the version and variant bit manipulation.
Testing the GUID Generation
To verify that the GuidUtil
class correctly generates UUID Version 4 compliant GUIDs, a test class is provided:
```java
@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); } } }
Test Class Breakdown:
GuidIsV4()
Test Method: This test method executes theNewGuid()
method 100 times and asserts that each generated GUID matches the Version 4 UUID pattern using a regular expression.Pattern.compile('[\w]{8}-[\w]{4}-4[\w]{3}-[89ab][\w]{3}-[\w]{12}')
: This regular expression specifically checks for the Version 4 UUID format. It verifies that the third section starts with ‘4’ (indicating version 4) and the fourth section starts with ‘8’, ‘9’, ‘a’, or ‘b’ (indicating the correct variant).System.assert(m.matches() == true)
: Confirms that each generated GUID string matches the defined pattern.
Conclusion
Generating random GUIDs, specifically UUID Version 4, is crucial for applications requiring unique identifiers without centralized generation. The GuidUtil
class provides a robust and cryptographically sound method to get random GUIDs in Apex, ensuring compliance with the UUID Version 4 standard. By understanding the underlying principles and utilizing the provided code example, developers can confidently implement UUID generation in their projects.