What is the best way to generate a GUID/UUID from Apex code (such as a trigger)? Preferably in the following format:




  • 1
    Is this of help ? peregrinusforce.com/2011/08/24/guid-generator-in-salesforce Commented Nov 5, 2012 at 22:04
  • @techtrekker: That looks very promising. Is it standalone and tested. I.e. do you have experience with it? Btw, you should post that as an answer. I'll give it a try and most likely will mark it as an answer.
    – Paul Sasik
    Commented Nov 5, 2012 at 22:09
  • I haven't personally tried it, which is why I posted it as a comment. Commented Nov 5, 2012 at 22:24

10 Answers 10


The answer provided by Paul Sasik above works, but is not a secure way of generating a UUID because of it's use of Math.Random(), which is not a cryptographically secure pseudo-random number generator.

One of two things should be done, either use Crypto.getRandomInteger() to generate the random integer or use the code below as a drop in replacement for the whole UUID generation routine:

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


  • Before you use or upvote this answer, please see the concerns in other answers about how "it doesn't generate valid UUIDs".
    – Jon Freed
    Commented May 30, 2019 at 13:47

After working with the code in techtrekker's link (in OP comments) and other resources I cobbled together a standalone, working class for generating GUIDs in Apex code:

Sample usage:

   if (acct.AccountUuid__c == null)
        acct.AccountUuid__c = GuidUtil.NewGuid();

Apex class:

global 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 = (Math.round(Math.random() * 255)-128) & 255;

            if (i==6) {
                nextByte = nextByte & 15;
                nextByte = nextByte | (4 << 4);

            if (i==8) {
                nextByte = nextByte & 63;
                nextByte = nextByte | 128;

            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);
  • 2
    The reference to StringUtils should be removed if this is supposed to be a standalone class. Good post nonetheless! Commented Aug 5, 2013 at 14:08
  • 4
    I have seen this procedure before. While it's very good, I have seen test methods once in a while give duplicates using this. The reason is the math.random which as we all know is not random at all. So the possibility exists of duplicates even with this. I think this needs to be increased to 1024 to lessen the possibility, but mostly - SALESFORCE; CREATE A STRING.NEWGUID() FUNCTION! Every language has it!
    – user7153
    Commented Mar 3, 2014 at 23:55
  • 2
    I know this is old, but: The code by Paul Sasik is good to generate some random ID, but it has no guarantee that it is "unique", as in GUID, or UUID. Regards, Allan
    – user16711
    Commented Jan 28, 2015 at 18:58

The answers given already either don't use a cryptographically secure random number or don't conform to UUID v4 standards. Here is a class and test that does both.

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;

And here is a test for it

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

You can create a nice 128-bit "GUID-lookalike" with a simple digest:

String result = 
        Crypto.generateDigest('MD5', Blob.valueOf(DateTime.now().getTime().format()))

This has a resolution of 1ms, so you might need to make sure at least 1ms has elapsed between each call. Alternatively:

String result = 
        Crypto.generateDigest('MD5', Blob.valueOf(Crypto.getRandomLong().format()))

Which guarantees a very high entropy value, but is more expensive (time-wise) than simply using the current time as the source.

In either case, you'll want to apply toUpperCase() to the result, and add in your dashes, if you need them to appear just like your example.


Built-in method

Since Spring '24, there is a built-in UUID class with a method to generate random UUID:

final UUID randomUuid = UUID.randomUUID();
final String randomUuidStr = randomUuid.toString();

You can generate one like this:

List<integer> guidASCIICode = new List<integer>();
while (guidASCIICode.size() < 32)
    double rnd = Math.random();
    integer alphanumeric = (integer)(rnd * 22);    //22 is range between
                                                   //ascii 0 and F 

    alphanumeric += 48;                            //shift random range up

    if (alphanumeric < 58 || alphanumeric > 65) {  //filter out some chars
String guid = String.fromCharArray( guidASCIICode ); //enjoy

If you care about the dashes, just insert them by your own.


Starting Spring '24, simply use the UUID system class to generate a random UUID(v4).

UUID uuIdV4 = UUID.randomUUID();  // returns a UUID instance, having a random UUID v4 Id.

And to get its String representation:

String uuIdV4Str = UUID.randomUUID().toString(); // 92a43945-23ca-4039-8450-7bfb6ade156a

A note on comparison:

A UUID instance can only be compared with another UUID instance.

From docs:

// UUIDs are equal when all the characters in the UUID are the same
String uuidStr = '707b2538-98bb-41e7-95e3-1d77bf42b102';
UUID fromStr = UUID.fromString(uuidStr);
UUID fromStr2 = UUID.fromString(uuidStr);

// A UUID is never equal to a String or any non-UUID object

The answer provided by Paul Sasik works and generates valid UUIDs, in the other hand the method provided by rev looks nicer, but it doesn't generate valid UUIDs because it does not agree with UUID conventions (see https://en.wikipedia.org/wiki/Universally_unique_identifier)

You can try to test the results of the following anonymous code at http://guid.us/Test/GUID

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


or using the follow JS regexp

var uuids = ['35706b3e-9f52-7d53-7ed3-d7f100b02a1c', //Generated by Crypo
'49b7d84b-478c-4eec-b53d-b6237666f30c', //Generated as Paul says
'c8f9caa0-b90b-438d-91bd-77fdea7a304b', //Generated as Paul says
'a44bedcb-5481-4780-aac9-3f106c2b8074', //Generated as Paul says
'83a15da9-c6c2-4c1f-8682-a51a79e6ae57', //Generated as Paul says
'fbc72910-32ce-4b60-a498-f4b3f450942f']; //Generated as Paul says
var re = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
for(var i=0; i<uuids.length; i++) {
  console.log(uuids[i] + '-'+re.test(uuids[i]));

For now I will use Paul's method, using Crypto.getRandomInteger() instead of Math.random(), but I think it is not entirely safe because there is a remote possibility of collisions

  • 1
    This is not an answer. It is a comment, mostly on Rev's answer. The provided code does not answer the question. Instead, it tests Rev's answer. (I am guessing this response is an "answer" instead of a comment or comments because of the minimum reputation needed to comment.)
    – Jon Freed
    Commented Jun 25, 2020 at 16:50

You can also use Auth.JWT() class for that:

(String)((Map<String, Object>) JSON.deserializeUntyped(new Auth.JWT().toJSONString())).get('jti')

It's not documented in https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_Auth_JWT.htm but in JSON Web Token, jti is a unique identifier for the JWT, so it seems to be valid.


This worked for me (where i is integer from a for loop):


You can probably find a valid SFDC prefix does not start with 0.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .