Search code examples
phpunique-key

How to generate unique secure random string in PHP?


I want to add random string as token for form submission which is generated unique forever. I have spent to much time with Google but I am confused which combination to use?

I found so many ways to do this when I googled:

1) Combination of character and number.

2) Combination of character, number and special character.

3) Combination of character, number, special character and date time.

Which combination may i use?

How many character of random string may I generate.?

Any other method which is secure then please let me know.?


Solution

  • Here are some considerations:

    Alphabet

    The number of characters can be considered the alphabet for the encoding. It doesn't affect the string strength by itself but a larger alphabet (numbers, non-alpha-number characters, etc.) does allow for shorter strings of similar strength (aka keyspace) so it's useful if you are looking for shorter strings.

    Input Values

    To guarantee your string to be unique, you need to add something which is guaranteed to be unique.

    • Random value is a good seed value if you have a good random number generator
    • Time is a good seed value to add but it may not be unique in a high traffic environment
    • User ID is a good seed value if you assume a user isn't going to create sessions at the exact same time
    • Unique ID is something the system guarantees is unique. This is often something that the server will guarantee / verify is unique, either in a single server deployment or distributed deployment. A simple way to do this is to add a machine ID and machine unique ID. A more complicated way to do this is to assign key ranges to machines and have each machine manage their key range.

    Systems that I've worked with that require absolute uniqueness have added a server unique id which guarantees a item is unique. This means the same item on different servers would be seen as different, which was what was wanted here.

    Approach

    Pick one more input values that matches your requirement for uniqueness. If you need absolute uniqueness forever, you need something that you control that you are sure is unique, e.g. a machine associated number (that won't conflict with others in a distributed system). If you don't need absolute uniqueness, you can use a random number with other value such as time. If you need randomness, add a random number.

    Use an alphabet / encoding that matches your use case. For machine ids, encodings like hexadecimal and base 64 are popular. For machine-readable ids, for case-insensitive encodings, I prefer base32 (Crockford) or base36 and for case-sensitive encodings, I prefer base58 or base62. This is because these base32, 36, 58 and 62 produce shorter strings and (vs. base64) are safe across multiple uses (e.g. URLs, XML, file names, etc.) and don't require transformation between different use cases.