/** * Copyright 2026 Angus.Fenying * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as NodeCrypto from 'node:crypto'; import { uuidToBuffer, uuidToString } from './Utils.js'; /** * The options for the UUIDv5 generator. */ export type IUuid5Options = Pick; /** * The pre-defined namespaces for UUIDv5. */ export enum EUuid5PredefinedNamespaces { DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8', URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8', OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8', X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8', } /** * The class for generating UUID in version 5. */ export class Uuid5Generator { /** * The namespace of the UUID, which must be a UUID string. */ public readonly namespace: string; private readonly _nsBin: Buffer; /** * Create a UUIDv5 generator bound to the specified namespace. * * @param opts The options for the UUIDv5 generator. */ public constructor(opts: IUuid5Options) { this.namespace = opts.namespace; this._nsBin = uuidToBuffer(opts.namespace); } /** * Generate a UUIDv5 based on the namespace and the name. * * @param name The name to generate the UUID from. * * @returns A UUIDv5 string. */ public generate(name: string): string { return Uuid5Generator.generate(this.namespace, name); } /** * Generate a UUIDv5 based on the namespace and the name, and return it as a Buffer. * * @param name The name to generate the UUID from. * * @returns A UUIDv5 in Buffer format, which is 16 bytes in total. */ public generateAsBuffer(name: string): Buffer { return Uuid5Generator.generateAsBuffer(this._nsBin, name); } /** * Generate a UUIDv5 based on the provided namespace and name. * * @param namespace The namespace for the UUID, which must be a UUID string or a Buffer of 16 bytes. * @param name The name to generate the UUID from. * @returns A UUIDv5 string. */ public static generate(namespace: string | Buffer, name: string): string { return uuidToString(Uuid5Generator.generateAsBuffer(namespace, name)); } /** * Generate a UUIDv5 based on the provided namespace and name, and return it as a Buffer. * * @param namespace The namespace for the UUID, which must be a UUID string or a Buffer of 16 bytes. * @param name The name to generate the UUID from. * @returns A UUIDv5 in Buffer format, which is 16 bytes in total. */ public static generateAsBuffer(namespace: string | Buffer, name: string): Buffer { const hash = NodeCrypto .createHash('sha1') .update(typeof namespace === 'string' ? uuidToBuffer(namespace) : namespace) .update(name) .digest(); hash[6] = (hash[6] & 0x0f) | 0x50; // the version, set to v5 (0101) hash[8] = (hash[8] & 0x3f) | 0x80; // clock_seq_hi_and_reserved, set to 10 return hash.subarray(0, 16); } }