生成可读的随机唯一ID


Generate a readable random unique ID

我需要生成唯一的事务ID。该系统允许使用数字、字母、连字符和下划线,但不允许使用句号。

我目前使用的功能是,

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

样本输出:

p_551171d3dd8a93-57457934

然而,我最近发现(a)uniqid()不一定是唯一的,(b)我的客户偶尔需要重新键入这些ID,比较它们,搜索它们,等等。当前的ID可读性不强,很难吸引眼球。(我原以为这些只是支付API的内部使用。我最近才意识到客户实际上在阅读这些内容。)

所以我想换成这个,

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

样本输出:

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

openssl_random_pseudo_bytes()推荐的生成随机唯一标识符的方法,但我担心这样做四次并进行连缀(我之所以这样做,是因为这是用连字符将其拆分以便于阅读的最简单方法)可能会影响它。我应该生成一个长字符串,然后对其进行操作以添加连字符吗?

或者,事实上,我应该做一些其他的事情吗?我真的不介意交易ID是什么样子的,只要它是唯一的,并且相对容易查看或重新键入。

连续多次调用openssl_random_pseudo_bytes应该不是问题。不管你读的是一个随机字节的长字符串还是许多随机字节的短字符串,它们仍然是随机的。我仍然会把代码改成这个,因为它更简单:

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

这个几乎看起来已经是一个UUID了,所以您实际上可能想使用其中一个。虽然随机字节应该这样做,但UUID被明确设计为全局唯一,具有足够高的概率,在实践中根本不需要担心。使用http://pecl.php.net/package/uuid或您的替代首选实现。

使用UUID。它可以由uniqid()和自定义算法形成,也可以使用库。如果使用UUID发生冲突,<在此处插入随机的巨大礼物>。

https://github.com/ramsey/uuid