所以我有一些代码需要使用 UUID 作为数据库 ID。为简单起见,我使用了 v4(随机),我看不出有任何真正的理由使用任何其他不那么随机的 UUID 版本。我的 UUID 类大致定义如下(简化):
class uuid {
public:
static uuid create_v4();
public:
// cut out for simplification...
public:
uint8_t bytes[16];
};
实际生成代码如下所示:
namespace {
uint32_t rand32() {
// we need to do this, because there is no
// gaurantee that RAND_MAX is >= 0xffffffff
// in fact, it is LIKELY to be 0x7fffffff
const uint32_t r1 = rand() & 0x0ff;
const uint32_t r2 = rand() & 0xfff;
const uint32_t r3 = rand() & 0xfff;
return (r3 << 20) | (r2 << 8) | r1;
}
}
uuid uuid::create_v4() {
static const uint16_t c[] = {
0x8000,
0x9000,
0xa000,
0xb000,
};
uuid uuid;
const uint32_t rand_1 = (rand32() & 0xffffffff);
const uint32_t rand_2 = (rand32() & 0xffff0fff) | 0x4000;
const uint32_t rand_3 = (rand32() & 0xffff0fff) | c[rand() & 0x03];
const uint32_t rand_4 = (rand32() & 0xffffffff);
uuid.bytes[0x00] = (rand_1 >> 24) & 0xff;
uuid.bytes[0x01] = (rand_1 >> 16) & 0xff;
uuid.bytes[0x02] = (rand_1 >> 8 ) & 0xff;
uuid.bytes[0x03] = (rand_1 ) & 0xff;
uuid.bytes[0x04] = (rand_2 >> 24) & 0xff;
uuid.bytes[0x05] = (rand_2 >> 16) & 0xff;
uuid.bytes[0x06] = (rand_2 >> 8 ) & 0xff;
uuid.bytes[0x07] = (rand_2 ) & 0xff;
uuid.bytes[0x08] = (rand_3 >> 24) & 0xff;
uuid.bytes[0x09] = (rand_3 >> 16) & 0xff;
uuid.bytes[0x0a] = (rand_3 >> 8 ) & 0xff;
uuid.bytes[0x0b] = (rand_3 ) & 0xff;
uuid.bytes[0x0c] = (rand_4 >> 24) & 0xff;
uuid.bytes[0x0d] = (rand_4 >> 16) & 0xff;
uuid.bytes[0x0e] = (rand_4 >> 8 ) & 0xff;
uuid.bytes[0x0f] = (rand_4 ) & 0xff;
return uuid;
}
这个 看起来 对我来说是正确的,但我最近从数据库收到一个错误,说我试图插入的 UUID 是重复的。由于这应该是非常不可能的,我必须假设我的代码可能存在问题。所以有人看到有什么不对吗?我的随机 UUID 生成不够随机吗?
注意: 我不能使用 boost 的随机数生成或者它的 UUID 库。我希望我可以,但是我被绑定(bind)到安装了特定版本库的特定系统,并且获得足够新的 boost 版本来拥有这些功能几乎是不可能的。
最佳答案
代码对我来说似乎是合理的。正如评论中所提到的,关于 rand() 是否是执行此任务的好选择存在一些问题,但是假设正在使用较新版本的库,您对它的使用似乎是生成 32 位数据的合理方法用于确保低位与高位一样随机(也在您的评论中提到)。
因此,只要 rand() 函数的性能还算不错,您就不太可能得到重复项。所以我的猜测是有一种不同的失败。想到的一些可能性:
只是胡乱猜测。其中,第三个是我最喜欢的,但如果我正在审查自己的代码,第 4 个将是我首先怀疑的。
关于c++ - 这个 UUID 生成代码有问题吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12322985/