安全唯一的纳米 ID 生成器,适用于多种应用
使用纳米 ID 生成安全、唯一且 URL 友好的标识符。为网页开发、分布式系统和数据库管理的各种应用自定义长度和字符集。
纳米 ID 生成器
生成的纳米 ID
可视化
文档
Nano ID 生成器
介绍
Nano ID 是一个微型、安全、URL友好的唯一字符串ID生成器。它旨在为分布式系统中的各种应用程序创建紧凑、非顺序且抗碰撞的标识符。此工具允许您生成具有可自定义长度和字符集的Nano ID。
Nano ID 的工作原理
Nano ID 是使用加密强随机数生成器和可自定义字母表生成的。默认实现使用:
- 64个字符的字母表(A-Za-z0-9_-),这是URL友好的
- 21个字符的长度
这种组合提供了ID长度和碰撞概率之间的良好平衡。
生成Nano ID的公式为:
1id = random(alphabet, size)
2
其中 random
是一个函数,从 alphabet
中选择 size
个字符,使用加密安全的随机数生成器。
Nano ID 的组成
自定义选项
-
长度:您可以调整生成的Nano ID的长度。默认是21个字符,但可以增加以提高唯一性或减少以缩短ID。
-
字母表:用于生成ID的字符集可以自定义。选项包括:
- 字母数字(默认):A-Za-z0-9_-
- 数字:0-9
- 字母:A-Za-z
- 自定义:您定义的任何字符集
安全性和唯一性
Nano ID 旨在:
- 不可预测:它们使用加密强的随机生成器。
- 唯一:在适当长度下,碰撞的概率极低。
碰撞概率取决于ID长度和生成的ID数量。碰撞的概率可以使用以下公式计算:
1P(collision) = 1 - e^(-k^2 / (2n))
2
其中:
- k 是生成的ID数量
- n 是可能的ID数量(字母表长度 ^ Nano ID 长度)
例如,使用默认设置(64个字符字母表,21个字符长度),您需要生成约1.36e36个ID才能有1%的碰撞概率。为了更好地理解这一点:
- 以每秒生成100万个ID的速度,大约需要433年才能有1%的碰撞概率。
- 在大多数实际应用中,您更有可能多次赢得彩票,而不是遇到Nano ID碰撞。
用例
Nano ID 适用于许多应用,包括:
- 数据库记录ID
- URL缩短器
- Web应用中的会话ID
- 临时文件名
- 难以协调的分布式系统
与其他ID方法的比较
方法 | 优点 | 缺点 |
---|---|---|
Nano ID | 短、URL友好、可自定义 | 非顺序 |
UUID | 标准化、非常低的碰撞概率 | 长(36个字符)、不友好URL |
自增 | 简单、顺序 | 不适用于分布式系统、可预测 |
ULID | 可按时间排序、URL友好 | 比Nano ID长(26个字符) |
KSUID | 可按时间排序、URL友好 | 比Nano ID长(27个字符) |
ObjectID | 包含时间戳和机器标识符 | 不够随机、长度为12字节 |
历史与发展
Nano ID 由 Andrey Sitnik 于2017年创建,作为UUID的更紧凑替代品。它旨在易于在各种编程语言和环境中使用,重点关注Web应用程序。
代码示例
以下是在不同编程语言中生成Nano ID的示例:
1// JavaScript
2import { nanoid } from 'nanoid';
3const id = nanoid(); // => "V1StGXR8_Z5jdHi6B-myT"
4
1## Python
2import nanoid
3id = nanoid.generate() # => "kqTSU2WGQPJzuWxfifTRX"
4
1## Ruby
2require 'nanoid'
3id = Nanoid.generate # => "7nj0iuNXoE0GnQNuH3b7v"
4
1// Java
2import com.aventrix.jnanoid.jnanoid.NanoIdUtils;
3String id = NanoIdUtils.randomNanoId(); // => "ku-gFr4Zx9QpfvLtO_8LH"
4
1// C#
2using Nanoid;
3var id = Nanoid.Generate(); // => "xGx2iKPNOEpGQBgJKU-Ow"
4
1// PHP
2<?php
3use Hidehalo\Nanoid\Client;
4$client = new Client();
5$id = $client->generateId(); // => "V1StGXR8_Z5jdHi6B-myT"
6?>
7
1// Rust
2use nanoid::nanoid;
3let id = nanoid!(); // => "V1StGXR8_Z5jdHi6B-myT"
4
1// Go
2import "github.com/matoous/go-nanoid/v2"
3id, err := gonanoid.New() // => "V1StGXR8_Z5jdHi6B-myT"
4
1// Swift
2import NanoID
3let id = NanoID.new() // => "V1StGXR8_Z5jdHi6B-myT"
4
最佳实践
- 根据您的唯一性要求选择适当的长度。
- 使用加密安全的随机数生成器。
- 如果使用自定义字母表,请确保它们具有足够的熵。
- 在数据库中将Nano ID存储为字符串,而不是整数。
- 在Nano ID列上使用索引以提高查询效率。
限制和注意事项
- Nano ID 不是顺序的,这可能会影响某些情况下的数据库性能。
- 它们不是人类可读的或按生成时间排序的。
- 自定义字母表可能会影响碰撞概率,应谨慎选择。
在Web应用中实现Nano ID生成器
要在Web应用中实现Nano ID生成器:
- 为您的后端语言安装Nano ID库。
- 创建一个生成并返回Nano ID的API端点。
- 使用客户端JavaScript在需要时调用API。
示例Express.js实现:
1const express = require('express');
2const { nanoid } = require('nanoid');
3
4const app = express();
5
6app.get('/generate-id', (req, res) => {
7 const id = nanoid();
8 res.json({ id });
9});
10
11app.listen(3000, () => console.log('Server running on port 3000'));
12
性能影响
Nano ID生成通常非常快速。在典型计算机上,它可以每秒生成数百万个ID。然而,请考虑以下几点:
- 生成速度可能因使用的随机数生成器而异。
- 自定义字母表或更长的长度可能会稍微影响性能。
- 在高负载系统中,考虑批量生成ID。
碰撞概率和缓解
为了减轻碰撞风险:
- 根据更高的唯一性要求增加Nano ID长度。
- 在应用程序逻辑中实现碰撞检查。
- 如果可能,使用更大的字母表。
在数据库中存储和索引Nano ID
在数据库中处理Nano ID时:
- 将它们存储为
VARCHAR
或等效的字符串类型。 - 使用Nano ID的完整长度以确保唯一性。
- 在Nano ID列上创建索引以加快查找速度。
- 考虑使用唯一约束以防止在数据库级别的重复。
创建包含Nano ID的表的示例SQL:
1CREATE TABLE users (
2 id VARCHAR(21) PRIMARY KEY,
3 name VARCHAR(100),
4 email VARCHAR(100)
5);
6
7CREATE INDEX idx_users_id ON users (id);
8
通过遵循这些指南并理解Nano ID的特性,您可以有效地在应用程序中实现和使用它们,以生成紧凑、唯一的标识符。
参考文献
- "Nano ID." GitHub, https://github.com/ai/nanoid. 访问于2024年8月2日。
- "UUID." Wikipedia, Wikimedia Foundation, https://en.wikipedia.org/wiki/Universally_unique_identifier. 访问于2024年8月2日。
- "碰撞概率计算器。" Nano ID 碰撞计算器, https://zelark.github.io/nano-id-cc/. 访问于2024年8月2日。
- "ULID 规范。" GitHub, https://github.com/ulid/spec. 访问于2024年8月2日。
- "KSUID:K可排序全局唯一ID。" GitHub, https://github.com/segmentio/ksuid. 访问于2024年8月2日。
- "ObjectID。" MongoDB 手册, https://docs.mongodb.com/manual/reference/method/ObjectId/. 访问于2024年8月2日。
反馈
点击反馈提示开始给这个工具反馈