0

I have a requirement of generating a unique 25 char alpha numeric #which has to be unique across different pods. I am using the following function.

public with sharing class GenerateUniqueKey {
    private static final Integer KEY_LENGTH = 25;
    public static String generateKey(){
        Blob aes = Crypto.generateAesKey(128);
        String randomValue = EncodingUtil.convertToHex(aes).left(KEY_LENGTH);
        return randomValue;
   }
}

So far, in the debug console, running it in a loop of 4071 generated unique output since the set has 4071 elements.

try{
   Set<String> generateKey = new Set<String>();
   for(integer i = 0; i < 4071 ; i++){
       String key = GenerateUniqueKey.generateKey(); 
       generateKey.add(key);
   }
   for(String s : generateKey){
      System.debug(s);
   }
   System.debug('>>>>> length : ' + generateKey.size());
}catch(Exception e){
    System.debug('>>>>> Exception : ' + e);
}

My question is does the above class guarantee unique 25 chars across pods in salesforce?

Why 4071? in loop, else maximum debug log reached.

2
  • Remove the debug and you can increase your test count. All you care about is the size of the set is equal to the number of iterations. At the end do system.assertEquals(4071,generateKey.size()); Turn down your log levels. You should be able to get a whole lot more to test
    – Eric
    Commented Apr 13, 2017 at 20:11
  • 1
    It may be helpful to take a look at this blog post about Windows GUIDs. It may be safer to use an analogous algorithm using things like the organization and record IDs rather than rely on random numbers being unique (which is generally not a property they guarantee). Commented Apr 13, 2017 at 20:29

2 Answers 2

3

No, it does not guarantee unique character strings, even within the same pod. With a fixed-length ciphertext, there is always the possibility of a collision. How likely is that? probably very, very small.

It's likely more than good enough for your use case, just not guaranteed to be unique. Truncating the AES key to 25 characters makes it more likely that you'll see a collision. Exactly how likely, I can't say (I did end up taking a few semesters of courses related to probability/statistics, but it's definitely not my forte).

The more important bit here is that without additional information, you can't possibly know if the same 25 characters of an AES-128 key has already been given out on another pod (or another org, if you're dealing with multiple salesforce orgs within your company).

A solution to this is to generate another key on a per-org basis (storing it in a hierarchy custom setting, perhaps), and use that as a prefix to the key you're generating on a per-record basis. Using your organaizationId may be an option to use as your per-org key. That way, it doesn't matter if you happen upon the cosmically unlikely event of generating the same AES-128 key in different orgs, the per-org prefix will be different, hence your GUID will be different.

1
  • 1
    Approximately 0.0000000000000000000000000000012%, FYI.
    – sfdcfox
    Commented Apr 13, 2017 at 20:34
3

This number generator is subject to the Birthday Problem, of course, but the odds of generating a previously used number will be approximately 1/2100, or approximately 0.788e-30 (about 0.00000000000000000000000000000000788% or so). Consider just encrypting (or even a digest using SHA-256) the Org ID, and using 25 characters from that result instead; you'll get a predictable value per org (in the sense that it is idempotent) with the same very small chance of collision.

4
  • If he has a total key space of 25 hexidecimal digits, wouldn't that make the chance of producing any particular key 1/(25^16) (4.3e-23)? Commented Apr 13, 2017 at 20:39
  • @IllusiveBrian Actually, 16 ^ 25... You're right, I've a typo, too, but the number of times you're multiplying by is the power, while the base is the number of possible values. :p
    – sfdcfox
    Commented Apr 13, 2017 at 20:44
  • @IllusiveBrian and 16^25 = 2^100. I just counted the number of bits per hex number and multiplied by 25 :P
    – sfdcfox
    Commented Apr 13, 2017 at 20:46
  • You're right, woops. Commented Apr 13, 2017 at 20:51

You must log in to answer this question.

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