Typescript で crypto だけを使ってランダム文字列生成

2023/11/13に公開

概要

ランダム文字列の生成には何を使っていますか?
nanoiduuid あたりがよく使われます.
しかし, これらを使わなくても Node.js 組み込みの crypto を使ってランダム文字列生成ができます.

crypto.randomBytes という関数を使って実装しています.

実装

  1. 生成される文字に偏りが出ないように, l を次のように定める.

    l = \max \{ x \in \mathbb{Z} ~~|~~ l_\mathrm{max} / x \in \mathbb{Z} \}

    ただし, l_\mathrm{max} \in \mathbb{Z}byteRange の値.

  2. 0 以上 l 以下のバイト列を生成する.

  3. バイト列の各成分に対応する文字からなる文字列を得る.

import { randomBytes } from "crypto";

const defaultCharset =
  "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789";

export const randomString = (
  length: number,
  {
    charset = defaultCharset,
    byteRange = 256,
  }: {
    charset?: string;
    byteRange?: number;
  },
): string => {
  if (length <= 0 || length > byteRange) {
    throw new Error(
      `length must satisfy 0 < length <= ${byteRange}, but ${length}.`,
    );
  }

  let result = "";

  while (result.length < length) {
    const bytes = randomBytes(length);

    for (const byte of bytes) {
      result += charset[byte % charset.length];
      if (result.length === length) break;
    }
  }

  return result;
};

Discussion