Whether you are generating unique referral codes, creating temporary passwords, or building robust test data, knowing how to generate a random string in Apex is a fundamental skill for any Salesforce developer. While the platform provides several utilities for security and encoding, choosing the right approach depends heavily on your specific requirements for character variety, string length, and execution speed.

In this guide, we will explore three distinct methods for generating random strings in Salesforce, evaluate their performance, and help you decide which one fits your use case.

Understanding the Need for Randomness in Salesforce

In the Salesforce ecosystem, you often encounter scenarios where a standard Auto-Number field isn't sufficient. You might need a code that is hard to guess for security reasons, or perhaps a string that contains a mix of uppercase letters, lowercase letters, and numbers for a external system integration.

When we talk about randomness in Apex, we primarily rely on the Crypto class. Unlike the standard Math.random() function, which returns a Double, the Crypto class provides methods like getRandomInteger() and generateAesKey(), which are designed for cryptographic strength.

Method 1: The Character Loop (Highly Flexible)

The most common way to generate a random string is to define a string of allowed characters and then loop through, picking characters at random indices. This method is highly readable and allows you to precisely control which characters (e.g., excluding ambiguous characters like 'O' and '0') are included.

public static String generateRandomString(Integer len) {
    final String chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
    String randStr = '';
    while (randStr.length() < len) {
       Integer idx = Math.mod(Math.abs(Crypto.getRandomInteger()), chars.length());
       randStr += chars.substring(idx, idx+1);
    }
    return randStr; 
}

How it works:

  1. Character Set: You define a final String containing every character you want to allow.
  2. Random Index: Crypto.getRandomInteger() generates a secure integer. We use Math.abs() to ensure it is positive and Math.mod() to keep it within the bounds of our string length.
  3. Concatenation: We use substring() to grab a single character and append it to our result.

Method 2: The Crypto/AES Approach (Maximum Speed)

If you need to generate many strings quickly—for instance, in a trigger processing a batch of 200 records—the loop method can become a bottleneck due to repeated string concatenation. A faster alternative is to leverage the Crypto.generateAesKey() method.

public static String generateRandomStringFast(Integer len) {
    Blob blobKey = Crypto.generateAesKey(192);
    String key = EncodingUtil.base64Encode(blobKey);
    // Remove non-alphanumeric characters often found in Base64
    key = key.replaceAll('[+/=]', '');
    return key.substring(0, len);
}

Pros and Cons:

  • Pros: This is significantly faster. In performance tests, generating 1,000 strings of 32 characters took roughly 158ms compared to over 5,000ms using the manual loop method.
  • Cons: You have less control over the character set. Base64 encoding includes +, /, and =, which you may need to strip out using Regex as shown above.

If you only need a hexadecimal string (0-9, a-f), you can simplify this further:

String hexKey = EncodingUtil.convertToHex(Crypto.generateAesKey(128));
return hexKey.substring(0, len);

Method 3: Optimized Character Arrays (High-Volume Alphanumeric)

For scenarios where you need high performance but want to maintain strict control over the alphanumeric character set, using an Integer array (representing ASCII character codes) is the most efficient path. This avoids the memory overhead of constant string concatenation.

static Integer[] charset;

static {
    charset = new Integer[0];
    for(Integer i = 48; i < 58; i++) charset.add(i); // 0-9
    for(Integer i = 65; i < 91; i++) charset.add(i); // A-Z
    for(Integer i = 97; i < 123; i++) charset.add(i); // a-z
}

public static String genRndStrFast(Integer len) {
    Integer[] chars = new Integer[len];
    Integer size = charset.size();

    for(Integer idx = 0; idx < len; idx++) {
        chars[idx] = charset[Math.mod(Math.abs(Crypto.getRandomInteger()), size)];
    }

    return String.fromCharArray(chars);
}

Why use fromCharArray?

In Apex, strings are immutable. Every time you use +=, a new string object is created in memory. By filling an array of Integers first and then converting that array to a string in a single operation (String.fromCharArray), you drastically reduce memory thrashing.

Performance Comparison: Which should you choose?

When deciding which algorithm to implement, consider the scale of your operation:

Method Best Use Case Performance (Short Strings) Performance (Long Strings)
Standard Loop Simple one-off generation Excellent Poor (Slow)
AES/Base64 Maximum raw speed Superior Superior
Char Array High-volume alphanumeric Good Excellent

Key Observation: Crypto.getRandomInteger() is a relatively "expensive" call in terms of CPU time. If you are generating a very short string (e.g., 5 characters), the overhead of the method call is the main factor. If you are generating very long strings (e.g., 10,000 characters), the efficiency of the string construction becomes the dominant factor.

Frequently Asked Questions

Is Crypto.getRandomInteger() truly random?

Yes, it uses a cryptographically secure pseudo-random number generator (CSPRNG). This is much safer for security-sensitive applications (like temporary tokens) than Math.random(), which is generally less predictable but not technically secure.

How do I ensure the generated string is unique in the database?

No matter how good your random generator is, there is always a theoretical chance of a "collision" (two records getting the same string). To handle this, you should: 1. Mark the target Custom Field as Unique and External ID in Salesforce. 2. Wrap your insertion logic in a try-catch block to handle DmlException if a collision occurs, allowing you to regenerate the string and retry.

Can I include special characters?

Absolutely. If you use Method 1 or Method 3, simply add the ASCII codes or characters for symbols like !@#$%^&* to your character set string or array.

Wrapping Up

Generating random strings in Apex is a task that can be approached in multiple ways. For most administrative tasks or simple triggers, the Standard Loop is perfectly acceptable and easy to maintain. However, if you are building a high-scale application or dealing with large data volumes, switching to the AES/Base64 approach or the Optimized Character Array method will keep your CPU limits in check.

Always remember to verify your requirements: do you need a specific length? A specific character set? Or just a unique identifier? Your answer will dictate which of these powerful Apex patterns is the best fit for your Salesforce org.