JavaScript toString() 진법 내용 정리

 

Notion 스타일 블록 에디터를 만들다 보니 각 블록에 고유 ID가 필요했습니다. 처음에는 UUID를 쓸까 했는데, 로컬 투두 앱에 36자짜리 ID는 좀 과하지 않나 싶었거든요. 그러다 JavaScript toString(base) 진법 변환을 알게 됐고, 7글자짜리 깔끔한 ID를 만들 수 있었습니다.

JavaScript toString(base)가 뭔지, 진법이 뭐고 왜 36을 쓰는지 정리해봤습니다.

고유 ID, 어떻게 만들지?

블록 에디터에서 각 블록에 고유 ID가 필요합니다. React의 key에도 쓰고, 블록을 찾거나 삭제할 때도 ID로 구분하니까요.

처음에는 crypto.randomUUID()를 쓸까 했는데, 결과가 이렇게 생겼습니다:

"550e8400-e29b-41d4-a716-446655440000"

이걸 보고 “로컬에서 돌아가는 투두 앱에 이 길이가 필요한가?” 싶었습니다. 블록이 많아봐야 수십 개인데 36자짜리 ID라니. 좀 더 짧고 가벼운 방법이 없나 찾아보다가 JavaScript toString(base) 진법 변환 패턴을 알게 됐습니다.

JavaScript toString(base) — 진법 변환이 뭔가요

Number.toString()에 숫자를 넣으면 해당 진법으로 변환해줍니다. 이게 생각보다 신기합니다:

Math.random() = 0.7293846...  (랜덤 소수)

.toString(10)  → "0.7293846..."     10진법 (기본값, 숫자 0~9만 사용)
.toString(16)  → "0.bab3f8c..."     16진법 (0~9 + a~f)
.toString(36)  → "0.q3m7kp2..."     36진법 (0~9 + a~z)

JavaScript toString(base)에서 base가 바로 진법입니다. 10을 넣으면 우리가 평소 쓰는 10진법, 16을 넣으면 16진법(hex), 36을 넣으면 36진법으로 변환됩니다.

진법이 커질수록 같은 숫자를 더 짧은 문자열로 표현할 수 있습니다. 이걸 ID 생성에 활용하는 겁니다.

왜 하필 36진법인가?

여기서 “왜 16이나 20이 아니라 36이지?” 하는 의문이 들 수 있는데요. 36은 JavaScript toString(base)에서 쓸 수 있는 최대 진법이기 때문입니다. 숫자 10개(09) + 알파벳 26개(az) = 36. 37 이상을 넣으면 RangeError가 나면서 에러가 터집니다.

같은 7글자로 만들 수 있는 ID 수를 비교하면 차이가 확 느껴집니다:

진법 사용 문자 7글자 경우의 수
10진법 0-9 1천만 개
16진법 0-9, a-f 약 2.7억 개
36진법 0-9, a-z 약 784억 개

짧으면서도 충돌 확률이 가장 낮은 조합입니다. 글자 수는 같은데 경우의 수가 이렇게 차이 나는 게 진법의 힘이라고 할 수 있겠습니다.

실제 사용 패턴

JavaScript toString(base) 진법 변환을 실제로 ID 생성에 쓸 때는 이런 패턴입니다:

Math.random().toString(36).substring(2, 9)
//                    ^^              ^^^^
//                  36진법        "0." 제거하고 7글자만 추출
//
// 결과: "q3m7kp2" 같은 짧은 랜덤 ID

Math.random()0.q3m7kp2... 같은 문자열을 만들어주고, substring(2, 9)로 앞의 "0."을 잘라내고 7글자만 가져오는 겁니다.

블록 에디터에서는 이런 식으로 썼습니다:

const newBlock = {
  id: Math.random().toString(36).substring(2, 9),  // "q3m7kp2"
  type: 'text',
  content: '',
  checked: false,
};

매번 새 블록을 만들 때마다 호출하면 되고, 코드도 한 줄이라 가볍습니다.

언제 이걸 쓰고 언제 UUID를 쓸까

JavaScript toString(base) 진법 변환으로 만든 ID는 편하지만 만능은 아닙니다. 상황에 맞게 골라야 합니다.

로컬에서 돌아가는 블록 에디터나 투두 앱 수준이면 toString(36)으로 충분합니다. 빠르고, 짧고, 읽기도 편하니까요.

다만 서버 간 동기화가 필요하거나 ID 충돌이 절대 나면 안 되는 상황이라면 crypto.randomUUID()를 쓰는 게 안전합니다. 길이는 길지만 충돌 확률이 사실상 0에 가깝거든요.

정리하면, 가벼운 프로젝트에서 짧은 ID가 필요할 때 JavaScript toString(base) 진법 변환은 아주 실용적인 선택입니다.

 

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다