Node.js용 무의존 랜덤 문자열 생성기 만들기 (보안 모드 포함)
Source: Dev.to
문제 개요
무작위 문자열 생성은 백엔드 개발자에게 흔한 작업입니다—ID, 토큰, 세션 키 등 다양한 용도로 사용됩니다.
많은 기존 구현은 다음과 같은 반복적인 문제를 가지고 있습니다:
- 보안에 민감한 값에
Math.random()사용 (암호학적으로 안전하지 않음). - 비효율적인 “생성 + 필터링” 로직: 전체 알파벳·숫자 집합에서 무작위로 생성한 뒤 원하는 유형에 맞지 않는 문자를 버리는 방식. 이는 반복을 낭비하고, 루프 안에서 정규식 오버헤드를 발생시키며, 무작위성에 따라 성능이 달라집니다.
- 단순한 문제에 무거운 의존성 끌어오기로 번들 크기와 유지 보수 부담이 증가합니다.
해결책
전체 문자 집합을 생성하고 필터링하는 대신, 적절한 문자 집합에서 직접 생성합니다. 알파벳, 숫자, 알파벳+숫자 각각에 대해 별도의 charset을 미리 정의하면 각 반복이 바로 사용 가능한 문자를 반환하므로 필터링이 필요 없습니다.
보안이 중요한 사용 사례(API 키, 인증 토큰, 세션 ID 등)에서는 Math.random()이 충분하지 않습니다. Web Crypto API(crypto.getRandomValues)와 **거부 샘플링(rejection sampling)**을 사용해 모듈로 바이어스를 피하고 charset의 모든 문자에 대해 균등한 확률을 보장하는 안전한 버전을 만들 수 있습니다.
장점
- 필요 시 암호학적 무작위성 제공.
- 거부 샘플링 덕분에 모듈로 바이어스 없음.
- 예측 가능한 성능—모든 루프 반복이 최종 문자열에 기여.
- 외부 의존성 0; 유틸리티가 가볍게 유지.
구현
// genkode – zero‑dependency random string & ID generator
export interface GenerateOptions {
/** Length of the generated string */
length: number;
/** Character set type: "alpha", "numeric", or "alphanumeric" (default) */
type?: "alpha" | "numeric" | "alphanumeric";
/** Use cryptographically secure randomness */
secure?: boolean;
}
/**
* Generate a random string according to the provided options.
*
* @example
* generateCode({ length: 12 });
* // => "a8KxP2LmQz"
*
* generateCode({ length: 12, type: "alpha" });
* // => "hJkLmNpQrStU"
*
* generateCode({ length: 12, secure: true });
* // => "4fG7hJ9kLm2Q"
*/
export function generateCode(options: GenerateOptions): string {
const { length, type = "alphanumeric", secure = false } = options;
const charsets = {
alpha: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
numeric: "0123456789",
alphanumeric: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
};
const charset = charsets[type];
const result: string[] = [];
if (secure && typeof crypto !== "undefined" && crypto.getRandomValues) {
// Secure generation with rejection sampling
const maxValidByte = 256 - (256 % charset.length);
while (result.length
핵심 정리
- 생성‑후‑필터링 패턴을 피하고 미리 올바른 문자 집합을 선택합니다.
- 보안 관련 무작위성이 필요할 때는 Web Crypto API를 사용합니다.
- 유틸리티를 간단하고 의존성 없이 유지해 번들 크기와 유지 보수 부담을 줄입니다.
대체 접근 방식이나 제안이 있다면 자유롭게 공유해 주세요.