0

I would like to generate unique alphanumeric max 50 character string based on a client ID. What is the chance of getting the same string by the way? I have more than one client, I don't want strings to be overlapped.

Here is what I planning to use:

static Random _Random = new Random();
static char[] _AllowedChars =
            Enumerable.Range(48, 10).Select(x => (char)x)
                .Concat(Enumerable.Range(65, 26).Select(x => (char)x))
                .Concat(Enumerable.Range(97, 26).Select(x => (char)x))
                .ToArray();
static string PseudoUniqueString(int maxLength = 50)
            => new string(Enumerable.Range(1, Math.Max(1, maxLength))
                .Select(x => _AllowedChars[_Random.Next(_AllowedChars.Length)])
                .ToArray());

Is there a way to add client ID (let's say 1) at the beginning of this string? I don't come up with another solution. Advice needed.

edit: This string will be used as a transaction number in a web API and there will be more than 1 client. Thats why I am thinking of adding client ID into this string.

Cenk
  • 13
  • 1
  • 10
  • 2
    If you have 50 characters to spare, you may as well use a GUID and save yourself the hassle of wondering if there's going to be a duplicate. – Jeroen Mostert Jun 20 '19 at 09:42
  • Why not simply use `Guid.NewGuid()`? It's practically guaranteed to be unique and quite random in the order it generates guids. (Well, not less random than Random.Next, anyway) – Zohar Peled Jun 20 '19 at 09:42
  • Encryption. If the user ID is guaranteed unique, then a good encryption of the user ID will also be unique. – rossum Jun 20 '19 at 11:42
  • Why do you need to generate a unique character string? Why can't you just use the client ID instead? See also [this answer](https://stackoverflow.com/questions/32795998/hiding-true-database-object-id-in-urls/32801130#32801130) and [my own answer on generating a unique identifier](https://stackoverflow.com/questions/51167523/how-to-generate-a-unique-and-random-number-for-a-primary-key-in-sql/56120914#56120914). – Peter O. Jun 20 '19 at 17:18
  • This string will be used as a transaction number in a web API. @PeterO. – Cenk Jun 20 '19 at 19:22
  • I don't understand why the client ID is required; if it is unique, then it is unique regardless of whether it is based on the ID. If it is based solely on the client ID then it is not truly random. Can you say more clearly what your real requirements are? Can you also say why you wish it to be random? Exactly what property of *randomness* is required for your solution? You may be trying to solve a security problem, and you have to be very careful when designing a security system that uses entropy. – Eric Lippert Jun 20 '19 at 19:31
  • I am worried about if there might be the same strings generated. Let's say there are 2 clients. Their ID's are 1 and 2. If I generate random unique strings with the code I posted and change the first character of the string with the ID's then there will never be worries. Am I wrong? – Cenk Jun 20 '19 at 19:35
  • is it max or exactly 50 characters? I feel like you are trying to hard at recreating a hash function, possibly because I dont understand the goal. For instance you could just murmur3hash(clientid+"%"+miliseconds since 1/1/2000) being a hash collision is super unlikely, though if you are trying to be cryptographic you should mention that. – Carter Jun 20 '19 at 20:45

1 Answers1

0

For your purposes, namely to generate a transaction number, you should create an identifier that includes a long random number (such as a GUID or a 128-bit or longer random number generated using the RNGCryptoServiceProvider class — not System.Random). It will be considered unique in one of the following cases:

  • Your application checks that transaction number for uniqueness against a database of transactions, not a database of clients (a transaction number does not necessarily contain information about the clients that caused that transaction). Or,
  • You concatenate the transaction's record number (automatically assigned by the database of transactions in most database software) to the random transaction number generated this way. Or,
  • Your application can tolerate the (theoretical) risk of generating a duplicate random number. This can be negligible if random GUIDs or longer random numbers are used as transaction numbers. This practice, however, ensures only practical uniqueness.
Peter O.
  • 32,158
  • 14
  • 82
  • 96
  • What I understand is GUID is enough, right? `string guid = Guid.NewGuid().ToString();` – Cenk Jun 21 '19 at 07:00
  • It's enough as long as "your application can tolerate the (theoretical) risk of generating a duplicate random number". Otherwise, you should either check the GUID (or other random number) for uniqueness or append a unique number (such as the row number in the transaction table) to that GUID (or other random number). – Peter O. Jun 21 '19 at 08:14