生成可读的随机唯一 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 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 或您的替代首选实现。
使用 UUID。它可以由 uniqid() 和自定义算法或使用库形成。如果你使用 UUID 发生碰撞,< insert random massive gift here >.
我需要生成唯一的交易 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 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 或您的替代首选实现。
使用 UUID。它可以由 uniqid() 和自定义算法或使用库形成。如果你使用 UUID 发生碰撞,< insert random massive gift here >.