English | 日本語 | Русский | 简体中文 | Bahasa Indonesia | 한국어 | العربية
JavaScriptのための小さく、安全で、URL友好的なユニークな文字列ID生成器。
「意味不明なレベルの完璧主義、 これは尊敬せざるを得ない。」
- 小さい。 118バイト(圧縮・brotli圧縮後)。依存関係なし。 Size Limitがサイズを管理。
- 安全。 ハードウェア乱数生成器を使用。クラスタでも利用可能。
- 短いID。 UUIDより大きなアルファベット(A-Za-z0-9_-)を使用。 そのためID長は36から21文字に短縮されています。
- 移植性。 Nano IDは20以上のプログラミング言語に移植されています。
import { nanoid } from 'nanoid'
model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" Made at Evil Martians, product consulting for developer tools.
Nano IDはUUID v4(ランダムベース)と十分に比較可能です。 ID内のランダムビット数は同様です(Nano IDで126ビット、UUIDで122ビット)、 そのため衝突確率も同様です:
10億分の1の確率で重複が発生するには、 103兆個のバージョン4 IDを生成する必要があります。
Nano IDとUUID v4の主な違いは2つあります:
- Nano IDはより大きなアルファベットを使用するため、同様のランダムビット数が 36文字ではなく21文字に詰め込まれています。
- Nano IDのコードはuuid/v4パッケージより4倍小さいです: 423バイトではなく118バイトです。
$ node ./test/benchmark.js
crypto.randomUUID 21,741,317 ops/sec
uuid v4 21,204,378 ops/sec
@napi-rs/uuid 10,236,615 ops/sec
uid/secure 10,567,676 ops/sec
@lukeed/uuid 8,647,481 ops/sec
nanoid 7,800,308 ops/sec
customAlphabet 9,697,350 ops/sec
nanoid for browser 576,759 ops/sec
secure-random-string 529,253 ops/sec
uid-safe.sync 526,459 ops/sec
Non-secure:
uid 31,379,525 ops/sec
nanoid/non-secure 3,678,505 ops/sec
rndm 3,767,185 ops/secテスト構成:Framework 13 7840U, Fedora 39, Node.js 21.6.
乱数生成器の理論に関する良い記事を参照してください: Secure random values (in Node.js)
-
予測不可能性。 安全でないMath.random()を使う代わりに、Nano IDは Node.jsではcryptoモジュールを、ブラウザではWeb Crypto APIを使用します。 これらのモジュールは予測不可能なハードウェア乱数生成器を使用します。
-
均一性。 random % alphabetはID生成器をコーディングする際によくある間違いです。 分布は均一ではなく、一部の記号が他のものより出現確率が低くなります。 そのため、総当たり攻撃の際に試行回数が減少します。Nano IDはより良いアルゴリズムを 使用し、均一性についてテストされています。
-
十分に文書化されている: Nano IDのすべてのハックは文書化されています。 ソースのコメントを参照してください。
-
脆弱性: セキュリティの脆弱性を報告するには、 Tideliftセキュリティ連絡先を使用してください。 Tideliftが修正と開示を調整します。
Nano ID 5はESMプロジェクト(importを使用)のテストやNode.jsスクリプトで動作します。
npm install nanoidNano IDは以下のいずれかの方法でCommonJSで使用できます:
-
require()を使用してNano IDをインポートできます。最新のNode.js 22.12 (標準で動作)またはNode.js 20(--experimental-require-moduleオプション付き)が必要です。
-
Node.js 18では、次のようにNano IDを動的にインポートできます:
let nanoid module.exports.createID = async () => { if (!nanoid) ({ nanoid } = await import('nanoid')) return nanoid() // => "V1StGXR8_Z5jdHi6B-myT" }
-
Nano ID 3.xを使用できます(まだサポートしています):
npm install nanoid@3
JSRはオープンなガバナンスと積極的な開発(npmとは対照的に)を持つnpmの代替です。
npx jsr add @sitnik/nanoidNode.js、Deno、Bunなどで使用できます。
// すべてのインポートで`nanoid`を`@sitnik/nanoid`に置き換える
import { nanoid } from '@sitnik/nanoid'Denoでは、deno add jsr:@sitnik/nanoidでインストールするか、
jsr:@sitnik/nanoidからインポートします。
クイックハックの場合、CDNからNano IDを読み込むことができます。ただし、読み込みパフォーマンスが低いため、本番環境での使用はお勧めしません。
import { nanoid } from 'https://cdn.jsdelivr.net/npm/nanoid/nanoid.js'Nano IDには2つのAPI:通常と非セキュアがあります。
デフォルトでは、Nano IDはURL友好的な記号(A-Za-z0-9_-)を使用し、 21文字のID(UUID v4と同様の衝突確率を持つ)を返します。
Nano IDを使用する安全で最も簡単な方法です。
まれに、ハードウェア乱数生成器のノイズ収集中にCPUを他の作業からブロックする場合があります。
import { nanoid } from 'nanoid'
model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"IDのサイズを小さくしたい場合(衝突確率を高める)、 サイズを引数として渡すことができます。
nanoid(10) //=> "IRFa-VaY2b"IDサイズの安全性をID衝突確率計算機で確認することを忘れないでください。
カスタムアルファベットや ランダム生成器も使用できます。
デフォルトでは、Nano IDはセキュリティと低衝突確率のためにハードウェアランダムバイト生成を使用します。セキュリティにそれほど関心がない場合は、ハードウェア乱数生成器がない環境でも使用できます。
import { nanoid } from 'nanoid/non-secure'
const id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ"customAlphabetは、独自のアルファベットとIDサイズでnanoidを作成できる関数を返します。
import { customAlphabet } from 'nanoid'
const nanoid = customAlphabet('1234567890abcdef', 10)
model.id = nanoid() //=> "4f90d13a42"import { customAlphabet } from 'nanoid/non-secure'
const nanoid = customAlphabet('1234567890abcdef', 10)
user.id = nanoid()カスタムアルファベットとIDサイズの安全性をID衝突確率計算機で確認してください。 より多くのアルファベットについては、nanoid-dictionaryのオプションを確認してください。
アルファベットは256記号以下でなければなりません。 そうでない場合、内部生成アルゴリズムのセキュリティは保証されません。
デフォルトサイズを設定するだけでなく、関数を呼び出す際にIDサイズを変更することもできます:
import { customAlphabet } from 'nanoid'
const nanoid = customAlphabet('1234567890abcdef', 10)
model.id = nanoid(5) //=> "f01a2"customRandomを使用すると、nanoidを作成し、アルファベットとデフォルトのランダムバイト生成器を置き換えることができます。
この例では、シードベースの生成器が使用されています:
import { customRandom } from 'nanoid'
const rng = seedrandom(seed)
const nanoid = customRandom('abcdef', 10, size => {
return new Uint8Array(size).map(() => 256 * rng())
})
nanoid() //=> "fbaefaadeb"randomコールバックは配列サイズを受け取り、ランダムな数値の配列を返す必要があります。
customRandomで同じURL友好的な記号を使用したい場合は、urlAlphabetを使用してデフォルトのアルファベットを取得できます。
const { customRandom, urlAlphabet } = require('nanoid')
const nanoid = customRandom(urlAlphabet, 10, random)なお、Nano IDのバージョン間でランダム生成器の呼び出しシーケンスが変更される場合があります。シードベースの生成器を使用している場合、同じ結果を保証するものではありません。
Reactのkey propにNano IDを使用する正しい方法はありません。なぜなら、keyはレンダー間で一貫性がある必要があるからです。
function Todos({ todos }) {
return (
<ul>
{todos.map(todo => (
<li key={nanoid()}>
{' '}
/* これはやめましょう */
{todo.text}
</li>
))}
</ul>
)
}代わりに、リストアイテム内で安定したIDを使用するようにしましょう。
const todoItems = todos.map(todo => <li key={todo.id}>{todo.text}</li>)安定したIDがない場合は、nanoid()の代わりにインデックスをkeyとして使用することをお勧めします:
const todoItems = todos.map((text, index) => (
<li key={index}>
{' '}
/* まだ推奨されませんが、nanoid()よりは優先されます。
アイテムに安定したIDがない場合のみ行ってください。 */
{text}
</li>
))ラベルと入力フィールドのように要素を関連付けるためだけにランダムなIDが必要な場合は、useIdが推奨されます。
このフックはReact 18で追加されました。
React Nativeには組み込みのランダム生成器がありません。次のポリフィルは
プレーンなReact NativeとExpo(39.x以降)で動作します。
react-native-get-random-valuesのドキュメントを確認し、インストールします。- Nano IDの前にインポートします。
import 'react-native-get-random-values'
import { nanoid } from 'nanoid'PouchDBとCouchDBでは、IDはアンダースコア_で始めることができません。
Nano IDはデフォルトでIDの先頭に_を使用する可能性があるため、
この問題を防ぐためにプレフィックスが必要です。
次のオプションでデフォルトのIDを上書きします:
db.put({
_id: 'id' + nanoid(),
…
})ターミナルでnpx nanoidを呼び出すことで、一意のIDを取得できます。
システムにNode.jsがあれば十分で、Nano IDをどこかにインストールする必要はありません。
$ npx nanoid
npx: installed 1 in 0.63s
LZfXLFzPPR4NNrgjlWDxn生成されるIDのサイズは--size(または-s)オプションで指定できます:
$ npx nanoid --size 10
L3til0JS4zカスタムアルファベットは--alphabet(または-a)オプションで指定できます
(この場合、--sizeが必須であることに注意してください):
$ npx nanoid --alphabet abc --size 15
bccbcabaabaccabNano IDでは、生成された文字列をTypeScriptで不透明な文字列(opaque strings)にキャストできます。 例えば:
declare const userIdBrand: unique symbol
type UserId = string & { [userIdBrand]: true }
// 明示的な型パラメータを使用:
mockUser(nanoid<UserId>())
interface User {
id: UserId
name: string
}
const user: User = {
// 自動的にUserIdにキャストされます:
id: nanoid(),
name: 'Alice'
}Nano IDは多くの言語に移植されています。これらのポートを使用して、 クライアント側とサーバー側で同じID生成器を持つことができます。
- C
- C#
- C++
- Clojure and ClojureScript
- ColdFusion/CFML
- Crystal
- Dart & Flutter
- Elixir
- Gleam
- Go
- Haskell
- Haxe
- Janet
- Java
- Kotlin
- MySQL/MariaDB
- Nim
- OCaml
- Perl
- PHP
- Python ネイティブ実装 辞書付きと 高速実装(Rustで書かれています)
- Postgres 拡張機能 とネイティブ関数
- R(辞書付き)
- Ruby
- Rust
- Swift
- Unison
- V
- Zig
その他の環境では、コマンドラインからIDを生成するためのCLIが利用可能です。
- IDサイズ計算機は、IDのアルファベットやサイズを調整する際の衝突確率を表示します。
nanoid-dictionaryはcustomAlphabetで使用する一般的なアルファベットを提供します。nanoid-goodはIDに不適切な単語が含まれていないことを確認します。
