diff --git a/src/security/id.util.test.ts b/src/security/id.util.test.ts index 373754f1..d6a27501 100644 --- a/src/security/id.util.test.ts +++ b/src/security/id.util.test.ts @@ -10,6 +10,7 @@ import { stringIdBase62, stringIdBase64, stringIdBase64Url, + stringIdNonAmbiguous, validate, } from '../index' @@ -91,3 +92,24 @@ test('stringIdBase64Url should have no padding', () => { }) }) }) + +describe('stringIdNonAmbiguous', () => { + test('default size', () => { + const id = stringIdNonAmbiguous() + expect(id.length).toBe(16) + expect(id).not.toContain('0') + expect(id).not.toContain('O') + expect(id).not.toContain('I') + expect(id).not.toContain('l') + }) + + test('custom size', () => { + const id = stringIdNonAmbiguous(100) + expect(id.length).toBe(100) + expect(id).not.toContain('0') + expect(id).not.toContain('O') + expect(id).not.toContain('1') + expect(id).not.toContain('I') + expect(id).not.toContain('l') + }) +}) diff --git a/src/security/id.util.ts b/src/security/id.util.ts index 835d7e47..74932377 100644 --- a/src/security/id.util.ts +++ b/src/security/id.util.ts @@ -2,6 +2,7 @@ import crypto from 'node:crypto' import { ALPHABET_ALPHANUMERIC, ALPHABET_ALPHANUMERIC_LOWERCASE, + ALPHABET_NONAMBIGUOUS, nanoIdCustomAlphabet, } from './nanoid' @@ -43,3 +44,13 @@ export function stringIdBase64(size = 16): string { export function stringIdBase64Url(size = 16): string { return crypto.randomBytes(size * 0.75).toString('base64url') } + +/** + * Generate cryptographically-secure string id with non-ambiguous characters only, + * e.g. missing O and 0, I and 1 and l etc. + * + * Default length is 16. + */ +export function stringIdNonAmbiguous(size = 16): string { + return stringId(size, ALPHABET_NONAMBIGUOUS) +} diff --git a/src/security/nanoid.ts b/src/security/nanoid.ts index 778f5a14..3080b78d 100644 --- a/src/security/nanoid.ts +++ b/src/security/nanoid.ts @@ -11,6 +11,7 @@ import { randomFillSync } from 'node:crypto' type RandomFn = (bytes: number) => Buffer +export const ALPHABET_NONAMBIGUOUS = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ' export const ALPHABET_NUMBER = '0123456789' export const ALPHABET_LOWERCASE = 'abcdefghijklmnopqrstuvwxyz' export const ALPHABET_UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'