toString(); HookManager::doAction('core.unique_id.after_generate', 'uuid', $uuid); return $uuid; } /** * NanoID를 생성합니다. * * random_bytes() 기반으로 암호학적으로 안전한 랜덤 문자열을 생성합니다. * Rejection sampling으로 모듈로 편향을 방지합니다. * * @param int $length 생성할 문자열 길이 * @param string|null $alphabet 사용할 문자 집합 (null이면 기본 알파벳) * @return string 생성된 NanoID */ public function generateNanoId(int $length = 16, ?string $alphabet = null): string { $alphabet = $alphabet ?? self::DEFAULT_ALPHABET; $alphabetSize = strlen($alphabet); HookManager::doAction('core.unique_id.before_generate', 'nanoid'); // 편향 없는 최대값 (rejection sampling 임계값) $maxValid = 256 - (256 % $alphabetSize); $id = ''; while (strlen($id) < $length) { $bytes = random_bytes($length - strlen($id)); for ($i = 0, $len = strlen($bytes); $i < $len && strlen($id) < $length; $i++) { $byte = ord($bytes[$i]); // 편향 방지: maxValid 이상의 값은 버림 if ($byte < $maxValid) { $id .= $alphabet[$byte % $alphabetSize]; } } } HookManager::doAction('core.unique_id.after_generate', 'nanoid', $id); return $id; } }