我想为事件生成票证。我需要生成很多票,因此我决定将票号作为UUID。问题是如何生成一个大的UUID列表,并且该列表会有所不同。
我知道只检查已经存在的列表中生成的每个新UUID的简单方法,但这并不是很友好的性能。 :)
我正在使用带有UUID v4的NodeJS。
谢谢!
答案 0 :(得分:1)
您可以创建一个空对象,并且每次生成UUID时,都向该对象添加一个属性,其中键是生成的UUID。当您生成另一个UUID时,只需检查object属性是否为undefined
即可查看它是否已被使用。
const uuids = [];
let uuidUsed = {};
const size = 10;
for (let i = 0; i < size; i++) {
let uuid = uuidv4();
while (uuidUsed[uuid] !== undefined) {
uuid = uuidv4();
}
uuidUsed[uuid] = true;
}
答案 1 :(得分:1)
您可以使用自家的UUID函数,该函数保证是[0 ... 2 128 )范围内的唯一伪随机整数。以下是基于Linear Contguential Generator的一种。常数取自here或here。您只需要保留上一个号码/ UUID即可生成下一个号码,而无需检查,因为只有在完整的2 128 之后才会重复。
代码依赖于BigInt,并经过v12节点测试
const a = 199967246047888932297834045878657099405n; // should satisfy a % 8n = 5n
const c = 1n; // should be odd
const m = (1n << 128n);
const mask = m - 1n;
function LCG128(state) {
return (BigInt(state) * a + c) & mask; // same as % m
}
q = 7654321n; // seed
q = LCG128(q);
q.toString(16); // first UUID
q = LCG128(q);
q.toString(16); // second UUID
q = LCG128(q);
q.toString(16); // third UUID
更新
只是对眼前的问题有更多的哲理:
LCG方法的优点在于,给定良好的乘数和进位,它可以将范围[0 ... 2 128 )唯一且可逆的映射到自身(对于64位数字,可以做到这一点) a
,c
或32位数字等等)。您甚至可以将counter用作输入,从0到2 128 -1开头,它将在相同范围内生成不可重复的数字,填充整个[0 ... 2 128 >)。因此,您知道,如果将它与以前的uuid链接在一起或使用counter,则发生碰撞的可能性为0。
答案 2 :(得分:0)
以下是446,538 IPs格式的列表,格式如下: id |日期|名称| uuid | ip |