npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@keepdb/uuidv8

v1.0.11

Published

UUID v8 with expiration and HMAC signature validation - Works on Node.js, Browser, and Edge Workers

Downloads

603

Readme

@keepdb/uuidv8

npm License

带过期时间和 HMAC 签名验证的 UUID v8 实现 - 支持 Node.js、浏览器和 Edge Workers

特性

  • 跨环境统一: 一套代码,Node.js 17+、浏览器、Edge Workers 全兼容
  • 过期时间: 内置过期时间戳,自动验证有效期
  • 场景隔离: 支持多种场景 ID(用户、会话、Token 等)
  • 签名防篡改: HMAC-SHA256 签名确保数据完整性
  • 零依赖: 纯 JS 实现,无外部依赖

快速开始

import { uuidv8 } from "@keepdb/uuidv8";

const result = await uuidv8(); // e.g. { uuid: "019be1e6-31c9-81bb-8011-1165a281ee18", ... }

使用自定义选项生成:

import { uuidv8, ContextId } from "@keepdb/uuidv8";

const result = await uuidv8({
  salt: 'my-secret-salt',
  ctxId: ContextId.USER,
  expiryDays: 365
});

console.log(result.uuid);
// e.g. "019be1e6-31c9-81bb-8011-1165a281ee18"

console.log(result.expiryDate.toISOString());
// e.g. "2026-01-21T18:51:58.281Z"

验证 UUID:

import { validateUUID } from "@keepdb/uuidv8";

const validation = await validateUUID("019be1e6-31c9-81bb-8011-1165a281ee18", {
  salt: 'my-secret-salt'
});

if (validation.valid) {
  console.log('有效凭证,剩余', validation.data.remainingDays, '天');
} else {
  console.log('无效:', validation.error);
}

命令行工具

# 生成单个 UUID
$ npx @keepdb/uuidv8
019be1e6-31c9-81bb-8011-1165a281ee18

# 批量生成
$ npx @keepdb/uuidv8 -n 4 -c user
019be1e6-31c9-81bb-8011-1165a281ee18
019be1e6-31c9-81c2-8022-3a8b9c4d5e6f
019be1e6-31c9-81c9-8033-4b5c6d7e8f9a
019be1e6-31c9-81d6-8044-5c6d7e8f9a0b

# 验证 UUID
$ npx @keepdb/uuidv8 -s SECRET -v 019be1e6-31c9-81bb-8011-1165a281ee18
✅ 有效
   场景: 0x0001
   过期: 2026-01-21T18:51:58.281Z
   剩余: 365 天

# JSON 输出
$ npx @keepdb/uuidv8 --json
[
  {
    "uuid": "019be1e6-31c9-81bb-8011-1165a281ee18",
    "expiryTimestamp": 1769021518281,
    "expiryDate": "2026-01-21T18:51:58.281Z",
    "ctxId": 1,
    "ctxHex": "0001",
    "expiryDays": 365
  }
]

CLI 参数:

  • -n <count> - 生成数量
  • -c <context> - 场景类型
  • -s <salt> - 签名密钥
  • -d <days> - 有效天数
  • -v <uuid> - 验证 UUID
  • --json / -j - JSON 格式输出
  • -h / --help - 帮助信息

UUID 结构

本实现生成的标识符具有以下位布局:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        expiry_ts_ms                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          expiry_ts_ms          |  ver  |  ctx  |    sig1     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|var|           sig2             |            sig3             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             sig3 (cont)                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

字段说明:

  • 48 位 expiry_ts_ms: 过期时间的 Unix 毫秒时间戳
  • 4 位 ver: 版本号,固定为 1000 (版本 8)
  • 4 位 ctx: 场景 ID(用户、会话、token 等)
  • 2 位 var: RFC 4122 变体,固定为 10
  • 80 位 sig: HMAC-SHA256 签名

场景 ID

import { ContextId } from "@keepdb/uuidv8";

ContextId.USER     // 0x1 - 用户 ID
ContextId.SESSION  // 0x2 - 会话 ID
ContextId.TOKEN    // 0x3 - 令牌 ID
ContextId.API_KEY  // 0x4 - API 密钥
ContextId.TEMP     // 0x5 - 临时凭证
ContextId.SYSTEM   // 0xF - 系统保留

API 参考

uuidv8(options?)

生成带过期时间和签名的 UUID v8。

import { uuidv8 } from "@keepdb/uuidv8";

const result = await uuidv8({
  salt: 'my-secret-salt',    // 签名密钥(必填)
  ctxId: ContextId.USER,     // 场景 ID(默认: ContextId.USER)
  expiryDays: 365            // 有效天数(默认: 365)
});

返回值: { uuid, expiryTimestamp, expiryDate, createdAt, createdDate, ctxId, ctxHex, expiryDays }

validateUUID(uuid, options?)

完整验证 UUID v8(格式 + 版本 + 场景 + 签名 + 过期时间)。

import { validateUUID } from "@keepdb/uuidv8";

const validation = await validateUUID(uuid, {
  salt: 'my-secret-salt',           // 签名密钥
  allowedContexts: [ContextId.USER], // 允许的场景 ID
  checkExpiry: true                  // 是否检查过期时间
});

返回值: { valid: boolean, error?: string, data?: {...} }

parseUUID(uuid)

解析 UUID v8 提取各部分信息。

import { parseUUID } from "@keepdb/uuidv8";

const info = parseUUID("019be1e6-31c9-81bb-8011-1165a281ee18");
// {
//   expiryTimestamp: 1769021518281,
//   expiryDate: Date(2026-01-21T18:51:58.281Z),
//   ctxId: 1,
//   ctxHex: '0001',
//   version: 8,
//   variant: 2,
//   signature: 'bb0111165a281ee18'
// }

isValidUUIDFormat(uuid)

检查字符串是否符合 UUID v8 格式。

import { isValidUUIDFormat } from "@keepdb/uuidv8";

const valid = isValidUUIDFormat("019be1e6-31c9-81bb-8011-1165a281ee18");
// true

validateSignature(uuid, salt)

验证 HMAC 签名是否匹配。

import { validateSignature } from "@keepdb/uuidv8";

const isValid = await validateSignature(uuid, 'my-secret-salt');
// true 或 false

calculateRemainingDays(uuid)

计算剩余有效天数。

import { calculateRemainingDays } from "@keepdb/uuidv8";

const days = calculateRemainingDays(uuid);
// "3.0"

类方法

所有函数也支持通过类方法调用:

import UUIDv8 from "@keepdb/uuidv8";

const result = await UUIDv8.generate('salt', UUIDv8.ContextId.USER, 365);
const info = UUIDv8.parse(result.uuid);
const validation = await UUIDv8.validate(result.uuid, { salt: 'salt' });

环境兼容性

| 环境 | 最低版本 | 状态 | | ------------------ | ---------------------- | ---------------------- | | Node.js | 17.0.0 | ✅ 全局 Web Crypto API | | 浏览器 | Chrome 37, Safari 11.1 | ✅ Web Crypto API | | Cloudflare Workers | - | ✅ Web Crypto API | | Vercel Edge | - | ✅ Web Crypto API | | Deno | 1.25+ | ✅ Web Crypto API |

安全建议

  1. Salt 保密: 签名密钥必须保密,建议通过环境变量配置
  2. HTTPS 传输: UUID 应通过 HTTPS 传输
  3. 定期轮换: 建议定期更换签名密钥
  4. 短生命周期: 敏感场景建议使用较短的有效期

许可证

MIT © 2025 Keepdb.com