59 lines
2.1 KiB
TypeScript
Executable File
59 lines
2.1 KiB
TypeScript
Executable File
/**
|
|
* UUID 生成器类
|
|
* 提供静态方法生成符合 RFC4122 标准的 UUID
|
|
*/
|
|
export class UUIDGenerator {
|
|
// 私有静态计数器
|
|
private static counter = 0;
|
|
|
|
/**
|
|
* 获取递增计数器值
|
|
*/
|
|
private static getCounter(): number {
|
|
this.counter = (this.counter + 1) % 0xffffff;
|
|
return this.counter;
|
|
}
|
|
|
|
/**
|
|
* 生成 UUID v4 (随机)
|
|
* @returns 返回符合 RFC4122 标准的 UUID 字符串
|
|
* @example
|
|
* UUIDGenerator.generate() // => "123e4567-e89b-12d3-a456-426614174000"
|
|
*/
|
|
public static generate(): string {
|
|
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
const buffer = new Uint8Array(16);
|
|
crypto.getRandomValues(buffer);
|
|
|
|
buffer[6] = (buffer[6] & 0x0f) | 0x40;
|
|
buffer[8] = (buffer[8] & 0x3f) | 0x80;
|
|
|
|
return ([
|
|
buffer.slice(0, 4).reduce((acc, val) => acc + ('00' + val.toString(16)).slice(-2), ''),
|
|
buffer.slice(4, 6).reduce((acc, val) => acc + ('00' + val.toString(16)).slice(-2), ''),
|
|
buffer.slice(6, 8).reduce((acc, val) => acc + ('00' + val.toString(16)).slice(-2), ''),
|
|
buffer.slice(8, 10).reduce((acc, val) => acc + ('00' + val.toString(16)).slice(-2), ''),
|
|
buffer.slice(10, 16).reduce((acc, val) => acc + ('00' + val.toString(16)).slice(-2), ''),
|
|
]).join('-');
|
|
}
|
|
|
|
// 改进的后备方案
|
|
const timestamp = Date.now();
|
|
const count = this.getCounter();
|
|
const random = Math.random() * 0xffffffff | 0;
|
|
|
|
const time_low = timestamp & 0xffffffff;
|
|
const time_mid = ((timestamp >>> 32) & 0xffff) ^ (count & 0xffff);
|
|
const time_hi = 0x4000 | (random & 0x0fff);
|
|
const clock_seq = 0x8000 | (random >>> 16 & 0x3fff);
|
|
const node = random >>> 32;
|
|
|
|
return (
|
|
time_low.toString(16).padStart(8, '0') + '-' +
|
|
time_mid.toString(16).padStart(4, '0') + '-' +
|
|
time_hi.toString(16).padStart(4, '0') + '-' +
|
|
clock_seq.toString(16).padStart(4, '0') + '-' +
|
|
node.toString(16).padStart(12, '0')
|
|
);
|
|
}
|
|
} |