staff_data/packages/common/src/tool/uuid.ts

59 lines
2.1 KiB
TypeScript
Raw Normal View History

2025-01-06 08:45:23 +08:00
/**
* 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')
);
}
}