检查这个,
List<String> list = new ArrayList<String>();
for (int i = 0; i < 10000; i++) {
String value = (""+UUID.randomUUID().getLeastSignificantBits()).substring(3, 20);
assertFalse(list.contains(value));
assertTrue(value.length() < 18);
list.add(value);
}
这种方法就像魅力一样传递。我的印象是,取最低有效位比取最高有效位要好一些。因为在最高有效位中,您为某些信息固定了 6 位,而最低有效位并非如此。因此,平均而言,我们需要生成 2^29 个 UUID 才能与最高有效位发生冲突,但 2^32 个 UUID 与最低有效位发生冲突。参考:SO 线程。我的假设是对的吗?
现在,在这里,我将从该方法中获得的最低有效位中再砍掉 2 个最高有效数字。我正在使用子字符串。请注意,我正在砍掉 2 个数字和一个符号位。这是否意味着现在我们平均需要生成 2^31 个 UUID 才能发生碰撞?
准确地说,我正在尝试生成一个不应超过 17 位长度的唯一标识符。它必须是一个整数,而不是 Java 类型的意义。我的方法有多可靠?
元信息:
实际上,我们正在与一些遗留系统集成,我们必须提供一些不超过 17 位的唯一编号。我假设他们将它作为数据库唯一键。在这种情况下,我们也可以使用序列,我首先提出了这一点。但他们对我说,如果我能想出一个随机数就好了,这样消费者就猜不到了。
据我所知,关于 Java 中 UUID 的 type-4 实现,我们平均需要生成 2^61 个 UUID 才能发生冲突。这是否意味着我们需要生成 2^32 来获得最低有效位的冲突,以及 2^29 来获得最高有效位的冲突?如果是,那么假设我们需要平均生成 2^31 以在切掉 2 个最左边的数字后在最低有效位上发生冲突是不正确的吗?
我也尝试使用SecureRandom
,但这也给了我 19 位数的长值。因此,我最终也先将其砍到数位。下面是代码。
List<String> list = new ArrayList();
Random random = new SecureRandom();
for (int i = 0; i < 10000; i++) {
String value = ""+random.nextLong().substring(2, 19);
assertFalse(list.contains(value));
assertTrue(value.length() < 18);
list.add(value);
}
yyMMddHHmmssSSS
我能想到的另一个选择是以“ +2-seq-digits”格式使用日期。但我想这将完全依赖于处理器,并且可以猜测。因为我不太确定在 99 轮之后我得到了毫秒的变化。也许我会,但这取决于处理器速度。不过,99 个同时请求是不太可能的。