简体   繁体   中英

Generate a readable random unique ID

I need to generate unique transaction IDs. The system allows digits, letters, hyphens, and underscores, but not full stops.

The function I'm currently using is,

generate_id() {
    $id = uniqid('P_', true);
    $id = str_replace('.', '-', $id);
    return $id;
}

Sample output:

P_551171d3dd8a93-57457934

However, I have recently found that (a) uniqid() isn't necessarily unique, and (b) my customer occasionally needs to retype these IDs, compare them, search for them, etc. The current IDs are not very readable, and are difficult to eyeball. (I had thought that these were purely for internal use in the payment API. I only recently realised that the customer was actually reading the things.)

So I was thinking of changing to this,

function generate_id() {
    $s = '';
    for ($i = 0; $i < 5; $i++) {
        if ($s) {
            $s .= '-';
        }
        $s .= bin2hex(openssl_random_pseudo_bytes(2));
    }
    return $s;
}

Sample output:

ced7-1cef-5331-193c-907d

openssl_random_pseudo_bytes() is the recommended way to generate random unique identifiers, but I fear that doing it four times and concatinating (which I'm doing only because that's the easiest way to split it up with hyphens for ease of reading) might compromise it. Should I generate one long string and then manipulate it to add hyphens?

Or, indeed, should I do something else altogether? I don't really mind what the transaction ID looks like, so long as it's unique and relatively easy to eyeball or retype.

Calling openssl_random_pseudo_bytes many times in a row should not be a problem. Whether you read one long string of random bytes or many short strings of random bytes doesn't matter, they're still random. I would still change that code to this, because it's simpler:

join('-', str_split(bin2hex(openssl_random_pseudo_bytes(40)), 4))

This almost looks like a UUID already, so you may actually want to use one of those instead. While random bytes should do, UUIDs are explicitly designed to be globally unique with a high enough probability that you don't need to worry about it in practice at all. Use http://pecl.php.net/package/uuid or your alternative preferred implementation.

Use a UUID. It can be formed from uniqid() and a custom algorithm or using a library. If you get a collision using UUID, < insert random massive gift here >.

https://github.com/ramsey/uuid

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM