MCPcopy Index your code
hub / github.com/ali-master/uuidv47

github.com/ali-master/uuidv47 @1.2.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release 1.2.0 ↗ · + Follow
75 symbols 290 edges 22 files 11 documented · 15% updated 9mo ago1.2.0 · 2025-10-07★ 1393 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README
<img src="https://github.com/ali-master/uuidv47/raw/1.2.0/assets/logo.svg" alt="UUIDv47 TypeScript Logo" width="120" height="120" />
<h1>UUIDv47</h1>

Reversible UUID v4/v7 transformation using SipHash-2-4

NPM Version License TypeScript Test Coverage Bundle Size Minified + Gzipped

⚡ Ultra-lightweight • 🚀 Zero dependencies • 📦 Just 2.25KB gzipped

🚀 What is UUIDv47?

UUIDv47 is a revolutionary approach to UUID management that allows you to reversibly transform UUIDs between v7 (time-ordered) and v4 (random-appearing) formats. This enables you to:

  • 🔒 Hide time-ordering from external APIs while maintaining internal chronological benefits
  • 🎭 Present v4 facades to clients while storing efficient v7 UUIDs internally
  • 🔐 Cryptographically secure transformations using SipHash-2-4 algorithm
  • High performance with >10,000 operations per second
  • 🔄 Perfect reversibility - no data loss in transformations
  • 📦 Tiny footprint - only 2.25KB gzipped with zero dependencies

🎯 Why Choose UUIDv47?

UUIDv47 is a lightweight library at just 5.71KB (2.25KB gzipped) that provides enterprise-grade UUID transformation capabilities with zero dependencies.

📋 Table of Contents

📦 Installation

# Using Bun (recommended)
bun add @usex/uuidv47

# Using npm
npm install @usex/uuidv47

# Using yarn
yarn add @usex/uuidv47

# Using pnpm
pnpm add @usex/uuidv47

Requirements

  • Node.js: 16.0.0+
  • TypeScript: 5.0+ (for TypeScript projects)
  • Runtime: Works with Node.js, Bun, Deno, and modern browsers

⚡ Quick Start

import { generateRandomKey, parseUUID, formatUUID, encodeV4Facade, decodeV4Facade } from '@usex/uuidv47';

// 1. Generate a secure transformation key
const key = generateRandomKey();

// 2. Parse your UUIDv7 (from your UUID generator)
const originalV7 = parseUUID('018f4e7c-3c4a-7000-8000-123456789abc');

// 3. Transform to v4 facade (for external APIs)
const v4Facade = encodeV4Facade(originalV7, key);
console.log(formatUUID(v4Facade));
// Output: "a1b2c3d4-e5f6-4789-9abc-def012345678" (appears random)

// 4. Transform back to original v7 (for internal use)
const decodedV7 = decodeV4Facade(v4Facade, key);
console.log(formatUUID(decodedV7));
// Output: "018f4e7c-3c4a-7000-8000-123456789abc" (original restored)

🧠 Core Concepts

The Problem UUIDv47 Solves

UUIDv7 provides excellent time-ordering properties but reveals creation timestamps to anyone who can parse them. UUIDv4 appears random but lacks useful ordering. UUIDv47 gives you both:

// Internal storage: UUIDv7 (time-ordered, efficient)
const internalId = "018f4e7c-3c4a-7000-8000-123456789abc";  // Created at specific timestamp

// External API: UUIDv4 facade (random-appearing, private)
const publicId = "a1b2c3d4-e5f6-4789-9abc-def012345678";   // Hides creation time

// They're the SAME identifier, just different representations!

How It Works

  1. Timestamp Encryption: The 48-bit timestamp in UUIDv7 is XORed with a SipHash-2-4 derived mask
  2. Random Bits Preserved: The random portion remains unchanged, maintaining uniqueness
  3. Version Swap: Version bits are changed between 4 and 7 during transformation
  4. Perfect Reversibility: Using the same key, transformations are completely reversible

Key Components

  • SipHash-2-4: Cryptographically secure hash function for generating encryption masks
  • 48-bit Timestamp: The time component that gets encrypted/decrypted
  • Transformation Key: 128-bit key (two 64-bit values) for secure transformations
  • UUID128: Buffer representation of 16-byte UUIDs for efficient processing

💡 Usage Examples

1. Basic Encode/Decode Operations

import { generateRandomKey, parseUUID, formatUUID, getUUIDVersion, encodeV4Facade, decodeV4Facade } from '@usex/uuidv47';

const key = generateRandomKey();
const v7UUID = parseUUID("018f4e7c-3c4a-7000-8000-123456789abc");

console.log(`Original UUIDv7: ${formatUUID(v7UUID)}`);
console.log(`Version: ${getUUIDVersion(v7UUID)}`); // 7

const v4Facade = encodeV4Facade(v7UUID, key);
console.log(`UUIDv4 Facade: ${formatUUID(v4Facade)}`);
console.log(`Version: ${getUUIDVersion(v4Facade)}`); // 4

const decodedV7 = decodeV4Facade(v4Facade, key);
console.log(`Decoded UUIDv7: ${formatUUID(decodedV7)}`);
console.log(`Matches original: ${decodedV7.equals(v7UUID)}`); // true

2. Service Integration Pattern

class UUIDTransformationService {
  private readonly key: UUIDv47Key;

  constructor(keyMaterial?: Buffer) {
    this.key = keyMaterial 
      ? createKeyFromBuffer(keyMaterial)
      : generateRandomKey();
  }

  // For external APIs - hide time ordering
  toPublicId(internalV7: string): string {
    const uuid = parseUUID(internalV7);
    const facade = encodeV4Facade(uuid, this.key);
    return formatUUID(facade);
  }

  // For internal processing - restore time ordering
  toInternalId(publicV4: string): string {
    const uuid = parseUUID(publicV4);
    const original = decodeV4Facade(uuid, this.key);
    return formatUUID(original);
  }
}

// Usage
const service = new UUIDTransformationService();
const internalId = "018f4e7c-3c4a-7000-8000-123456789abc";
const publicId = service.toPublicId(internalId);
const recoveredId = service.toInternalId(publicId);

console.log({ internalId, publicId, recoveredId });
// { 
//   internalId: "018f4e7c-3c4a-7000-8000-123456789abc",
//   publicId: "a1b2c3d4-e5f6-4789-9abc-def012345678", 
//   recoveredId: "018f4e7c-3c4a-7000-8000-123456789abc"
// }

3. Multi-Tenant Key Management

class MultiTenantUUIDService {
  private readonly tenantKeys = new Map<string, UUIDv47Key>();

  setTenantKey(tenantId: string, keyMaterial: Buffer): void {
    this.tenantKeys.set(tenantId, createKeyFromBuffer(keyMaterial));
  }

  encodeForTenant(tenantId: string, v7UUID: string): string {
    const key = this.tenantKeys.get(tenantId);
    if (!key) throw new Error(`No key found for tenant: ${tenantId}`);

    const uuid = parseUUID(v7UUID);
    const facade = encodeV4Facade(uuid, key);
    return formatUUID(facade);
  }

  decodeForTenant(tenantId: string, v4Facade: string): string {
    const key = this.tenantKeys.get(tenantId);
    if (!key) throw new Error(`No key found for tenant: ${tenantId}`);

    const uuid = parseUUID(v4Facade);
    const original = decodeV4Facade(uuid, key);
    return formatUUID(original);
  }
}

4. Batch Processing

// Process 1000 UUIDs efficiently
const key = generateRandomKey();
const v7UUIDs = generateV7UUIDs(1000); // Your UUID generation

console.time('Batch Encode');
const facades = v7UUIDs.map(uuid => encodeV4Facade(uuid, key));
console.timeEnd('Batch Encode'); // ~10ms for 1000 UUIDs

console.time('Batch Decode');
const decoded = facades.map(facade => decodeV4Facade(facade, key));
console.timeEnd('Batch Decode'); // ~10ms for 1000 UUIDs

// Verify all transformations are perfect
const allMatch = decoded.every((uuid, i) => uuid.equals(v7UUIDs[i]));
console.log(`All roundtrips successful: ${allMatch}`); // true

5. Error Handling

const key = generateRandomKey();

try {
  // This will throw - can only encode v7 UUIDs
  const v4UUID = parseUUID("a1b2c3d4-e5f6-4000-8000-123456789abc");
  encodeV4Facade(v4UUID, key);
} catch (error) {
  console.log(error.message); // "Input UUID must be version 7"
}

try {
  // This will throw - can only decode v4 UUIDs
  const v7UUID = parseUUID("018f4e7c-3c4a-7000-8000-123456789abc");
  decodeV4Facade(v7UUID, key);
} catch (error) {
  console.log(error.message); // "Input UUID must be version 4"
}

try {
  // This will throw - invalid UUID format
  parseUUID("invalid-uuid-string");
} catch (error) {
  console.log(error.message); // "Invalid UUID string length: expected 36, got 19"
}

6. UUID v7 Timestamp Extraction

import { parseUUID, extractTimestampFromV7, formatUUID } from '@usex/uuidv47';

// Extract timestamp from a UUID v7
const v7UUID = parseUUID("018f4e7c-3c4a-7000-8000-123456789abc");
const timestamp = extractTimestampFromV7(v7UUID);

console.log(`UUID v7: ${formatUUID(v7UUID)}`);
console.log(`Timestamp: ${timestamp.getTime()} ms`);
console.log(`Date: ${timestamp.toISOString()}`); // "2024-10-07T23:15:45.610Z"
console.log(`Local: ${timestamp.toLocaleString()}`);

// Compare creation times of multiple UUIDs
const uuid1 = parseUUID("018f4e7c-3c4a-7000-8000-111111111111");
const uuid2 = parseUUID("018f4e7c-4000-7000-8000-222222222222");
const uuid3 = parseUUID("018f4e7c-5000-7000-8000-333333333333");

const date1 = extractTimestampFromV7(uuid1);
const date2 = extractTimestampFromV7(uuid2);
const date3 = extractTimestampFromV7(uuid3);

console.log("UUIDs in chronological order:");
console.log(`  ${formatUUID(uuid1)}: ${date1.toISOString()}`);
console.log(`  ${formatUUID(uuid2)}: ${date2.toISOString()}`);
console.log(`  ${formatUUID(uuid3)}: ${date3.toISOString()}`);

// Use for sorting, filtering by date, etc.
const uuids = [uuid3, uuid1, uuid2];
const sortedByTime = uuids.sort((a, b) => {
  const timeA = extractTimestampFromV7(a).getTime();
  const timeB = extractTimestampFromV7(b).getTime();
  return timeA - timeB;
});

// Error handling - only works with v7 UUIDs
try {
  const v4UUID = parseUUID("a1b2c3d4-e5f6-4000-8000-123456789abc");
  extractTimestampFromV7(v4UUID);
} catch (error) {
  console.log(error.message); // "Cannot extract timestamp: UUID is version 4, expected version 7"
}

📚 API Reference

Core Transformation Functions

encodeV4Facade(uuidV7: UUID128, key: UUIDv47Key): UUID128

Transform a UUIDv7 into a UUIDv4 facade that appears random but can be reversed.

import { encodeV4Facade, parseUUID, generateRandomKey } from '@usex/uuidv47';

const key = generateRandomKey();
const v7 = parseUUID("018f4e7c-3c4a-7000-8000-123456789abc");
const v4Facade = encodeV4Facade(v7, key);

decodeV4Facade(uuidV4Facade: UUID128, key: UUIDv47Key): UUID128

Transform a UUIDv4 facade back to its original UUIDv7 format.

import { decodeV4Facade } from '@usex/uuidv47';

const originalV7 = decodeV4Facade(v4Facade, key);

Enhanced Core Functions with Options

encodeV4FacadeWithOptions(uuidV7: UUID128, key: UUIDv47Key, options?: UUIDOperationOptions): UUID128

Encode with performance optimization options.

import { encodeV4FacadeWithOptions } from '@usex/uuidv47';

// Skip validation for trusted input (faster)
const encoded = encodeV4FacadeWithOptions(v7, key, { skipValidation: true });

decodeV4FacadeWithOptions(uuidV4Facade: UUID128, key: UUIDv47Key, options?: UUIDOperationOptions): UUID128

Decode with performance optimization options.

import { decodeV4FacadeWithOptions } from '@usex/uuidv47';

// Skip validation for maximum performance
const decoded = decodeV4FacadeWithOptions(v4Facade, key, { skipValidation: true });

Batch Processing Functions

batchEncodeV4Facade(uuids: UUID128[], key: UUIDv47Key): UUID128[]

Process multiple UUIDs efficiently in a single operation.

import { batchEncodeV4Facade } from '@usex/uuidv47';

const v7UUIDs = [uuid1, uuid2, uuid3]; // Array of v7 UUIDs
const v4Facades = batchEncodeV4Facade(v7UUIDs, key);

batchDecodeV4Facade(uuids: UUID128[], key: UUIDv47Key): UUID128[]

Decode multiple UUIDs efficiently in a single operation.

import { batchDecodeV4Facade } from '@usex/uuidv47';

const originalUUIDs = batchDecodeV4Facade(v4Facades, key);

batchEncodeV4FacadeWithOptions(uuids: UUID128[], key: UUIDv47Key, options?: UUIDOperationOptions): UUID128[]

Batch encoding with performance options.

import { batchEncodeV4FacadeWithOptions } from '@usex/uuidv47';

// Use individual processing instead of batch optimization
const encoded = batchEncodeV4FacadeWithOptions(uuids, key, { 
  useBatchProcessing: false,
  skipValidation: true 
});

batchDecodeV4FacadeWithOptions(uuids: UUID128[], key: UUIDv47Key, options?: UUIDOperationOptions): UUID128[]

Batch decoding with performance options.

import { batchDecodeV4FacadeWithOptions } from '@usex/uuidv47';

const decoded = batchDecodeV4FacadeWithOptions(facades, key, {
  useBatchProcessing: false,
  skipValidation: true
});

UUID Parsing and Formatting Functions

parseUUID(uuidString: string): UUID128

Convert a UUID string to internal Buffer representation.

import { parseUUID } from '@usex/uuidv47';

const uuid = parseUUID("018f4e7c-3c4a-7000-8000-123456789abc");

formatUUID(uuid: UUID128): string

Convert a UUID Buffer to standard string format.

import { formatUUID } from '@usex/uuidv47';

const uuidString = formatUUID(uuid); // "018f4e7c-3c4a-7000-8000-123456789abc"

parseUUIDWithOptions(uuidString: string, options?: UUIDOperationOptions): UUIDParseResult

Extension points exported contracts — how you extend this code

UUIDv47Key (Interface)
(no doc)
src/types.ts
UUIDOperationOptions (Interface)
(no doc)
src/types.ts
UUIDParseResult (Interface)
(no doc)
src/types.ts

Core symbols most depended-on inside this repo

parseUUID
called by 57
src/uuid.ts
createKey
called by 54
src/key-management.ts
generateRandomKey
called by 39
src/key-management.ts
encodeV4Facade
called by 37
src/core.ts
isValidKey
called by 35
src/key-management.ts
formatUUID
called by 34
src/uuid.ts
getUUIDVersion
called by 28
src/uuid.ts
decodeV4Facade
called by 28
src/core.ts

Shape

Function 36
Method 23
Class 12
Interface 3
Enum 1

Languages

TypeScript100%

Modules by API surface

examples/index.ts20 symbols
src/uuid.ts10 symbols
benchmarks/real-world.bench.ts10 symbols
src/core.ts8 symbols
src/key-management.ts6 symbols
src/byte-operations.ts6 symbols
test/sip-hash.spec.ts5 symbols
src/types.ts3 symbols
src/sip-hash.ts3 symbols
test/index.spec.ts1 symbols
test/core.spec.ts1 symbols
src/constants.ts1 symbols

For agents

$ claude mcp add uuidv47 \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page