82 lines
4.4 KiB
Markdown
82 lines
4.4 KiB
Markdown
---
|
|
title: blog-topic / ulid-crockford-base32-excluded-letters-2026-06-01
|
|
source_type: blog-topic
|
|
status: raw
|
|
related_branches: [feature-resource-identifier-contract]
|
|
related_projects: [ca-tmpl]
|
|
tags: [blog-topic, ca-tmpl, ulid, crockford-base32, identifier, validation]
|
|
created: 2026-06-01
|
|
status_label: ready-for-canonical
|
|
target_audience: backend-engineer
|
|
inspiration_url:
|
|
archive_url:
|
|
---
|
|
|
|
# blog-topic: ulid-crockford-base32-excluded-letters-2026-06-01
|
|
|
|
> Layer: `raw/blog-topics/` — 채용공고가 아닌 작업·학습·트러블슈팅에서 나온 블로그 글감 원석.
|
|
|
|
## Parent / 부모
|
|
|
|
- [[raw/branch-notes/feature-resource-identifier-contract]] — ULID 채택 + Crockford base32 charset(D2) 결정.
|
|
- [[raw/errors/ulid-fixture-crockford-u-self-inconsistency-2026-06-01]] — "ULID처럼 보이는" placeholder가 실제로는 invalid였던 사건.
|
|
|
|
## 트리거 / Trigger
|
|
|
|
- 트리거 유형: `branch-work` / `error`
|
|
- 트리거 날짜: 2026-06-01
|
|
- 트리거 연결 노트: [[raw/errors/ulid-fixture-crockford-u-self-inconsistency-2026-06-01]]
|
|
|
|
## 글감 / Topic seed
|
|
|
|
- 한 문장 요지: ULID는 Crockford base32를 쓰고, Crockford는 사람이 헷갈리는 **I, L, O, U를 의도적으로 제외**한다. 그래서 "대충 26자 영숫자"로 만든 예시 ULID는 빌드에서 터진다 — charset 결정과 예시 값은 *같은 파서로* 교차검증해야 한다.
|
|
- 떠오른 계기: spec의 D19 fixture `01HRGC7K2N4F6P8Q0R2S4T6U8V`가 23번째 'U' 때문에 자기 자신의 regex/charset을 위반.
|
|
- 예상 제목 후보:
|
|
- ULID 식별자에 왜 I/L/O/U가 없을까 (Crockford base32의 사람-친화 설계)
|
|
- "유효해 보이는" 식별자가 빌드를 깨뜨릴 때: 문서 예시 값을 단위테스트하라
|
|
- UUID dashed vs ULID Crockford: URL/로그/DB에서의 실전 차이
|
|
|
|
## 핵심 주장 후보 / Claim candidates
|
|
|
|
- Crockford base32 alphabet = `0123456789ABCDEFGHJKMNPQRSTVWXYZ` (I/L/O/U 제외, 32자) — case-insensitive 디코딩 시 `I/L→1`, `O→0` 정규화.
|
|
- ULID = 48bit ms timestamp + 80bit random, 26자, lexicographic 정렬 = 시간 정렬. URL-safe(RFC 3986 unreserved 진부분집합)라 percent-encoding 불필요.
|
|
- 문서에 박는 예시 식별자는 라이브러리 파서(`ulid-creator`의 `Ulid.from`)로 1회 검증한 값만 써라 — 구현이 곧 spec의 단위테스트다.
|
|
- 외부 검증 가능한 값(ULID spec 공식 예제 `01ARZ3NDEKTSV4RRFFQ69G5FAV`)을 fixture로 쓰면 면접/포트폴리오에서 "왜 이 값?"에 정당성이 생긴다.
|
|
|
|
## Outline seed
|
|
|
|
1. "유효해 보이는 ID"와 실제 parser가 통과하는 ID는 다르다.
|
|
2. Crockford base32 alphabet과 ULID charset 경계를 설명한다.
|
|
3. 문서 예시 값도 production parser로 검증하는 contract fixture로 다룬다.
|
|
|
|
## Canonical 전환 후보 / Canonical extraction candidates
|
|
|
|
- `wiki/projects/ca-tmpl/resource-identifier-format.md` 후보:
|
|
- ca-tmpl ULID resource identifier 결정과 fixture/example 검증 경계.
|
|
- `wiki/concepts/resource-identifier-format.md` 후보:
|
|
- ULID/Crockford base32 alphabet 일반 개념.
|
|
|
|
## Sources / 근거 후보
|
|
|
|
- [[raw/branch-notes/feature-resource-identifier-contract]] — ULID resource identifier 결정.
|
|
- [[raw/errors/ulid-fixture-crockford-u-self-inconsistency-2026-06-01]] — invalid fixture 사건.
|
|
|
|
## 미해결 / Unknown
|
|
|
|
- 아직 확인해야 할 사실: ULID official spec claim과 `ulid-creator` parser 동작을 concept 문서에서 어느 수준까지 분리할지.
|
|
- 과장하면 안 되는 부분: ULID가 UUID보다 항상 낫다고 쓰지 않는다.
|
|
- 블로그로 쓰기 전에 필요한 canonical 정제: 이미 `wiki/projects/ca-tmpl/resource-identifier-format.md`에 연결됨. concept 쪽 claim-backed 표현은 blogify 전 확인한다.
|
|
|
|
## Decision / 처리 결정
|
|
|
|
- 액션: `promote-to-canonical`
|
|
- 이유: `wiki/projects/ca-tmpl/resource-identifier-format.md` 에 ULID/Crockford base32 예시 검증 글감으로 반영했다.
|
|
- 다음 단계: source canonical이 `verified` 상태이므로 이후 `blogify` 대상으로 삼을 수 있다. 단 ULID가 UUID보다 항상 우월하다고 쓰지 않는다.
|
|
|
|
## Related / 관련
|
|
|
|
- 관련 branch: [[raw/branch-notes/feature-resource-identifier-contract]]
|
|
- 관련 error: [[raw/errors/ulid-fixture-crockford-u-self-inconsistency-2026-06-01]]
|
|
- 관련 interview prep:
|
|
- derived blog: 생성 전. 생성 시 `wiki/blog/ulid-crockford-base32-excluded-letters-YYYY-MM-DD.md` 후보
|