# ID에서 시각적으로 모호한 문자의 이해와 회피

> Clean Markdown view of GeekNews topic #14479. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=14479](https://news.hada.io/topic?id=14479)
- GeekNews Markdown: [https://news.hada.io/topic/14479.md](https://news.hada.io/topic/14479.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-04-24T10:18:53+09:00
- Updated: 2024-04-24T10:18:53+09:00
- Original source: [gajus.com](https://gajus.com/blog/avoiding-visually-ambiguous-characters-in-ids)
- Points: 4
- Comments: 3

## Topic Body

### ID에서 시각적으로 모호한 문자 이해하기

- 시각적으로 모호한 문자란 특정 글꼴이나 손글씨에서 구별하기 어려운 문자들을 의미함
  - O/0, I/l/1/7, 5/S, 2/Z, 8/B, 6/G, 9/q/g 등이 이에 해당
- 이런 문자들은 데이터 입력시 오류와 혼란을 야기할 수 있음
  - 사용자가 'O'와 '0'을 구별하기 어려워 잘못된 코드를 입력하는 등 불편한 사용자 경험을 초래
- ID가 구두로 전달되거나 손으로 적어야 하는 상황에서 특히 중요함 
  - 고객지원, 할인코드, 추적코드, 에러ID, 제품ID 등

### 대소문자 구분 여부 결정하기 

- ID에서 대소문자를 구분할지 여부를 결정해야 함
  - 대소문자 구분시 시각적 모호성을 배제하고 선택 가능한 문자는 53개
  - 대소문자 구분 없을 시 선택 가능한 문자는 22개
- ID 길이가 5자리일 경우 가능한 ID 수:
  - 대소문자 구분: 53^5 = 418,195,493개  
  - 대소문자 구분 없음: 22^5 = 5,153,632개
- 그러나 ID 길이가 늘어날수록 가능한 ID 수는 기하급수적으로 증가함
- 따라서 ID 길이와 시각적 모호성 가능성 간의 절충점을 찾아야 함
- 또한 대소문자를 모두 사용하면 대소문자를 구분하지 않는 서드파티 시스템에서 예상치 못한 문제가 발생할 수 있음

### 시각적으로 명확한 문자 세트

- 가독성을 우선으로 할 경우 다음과 같은 문자 세트 사용 추천:
  - [ "a", "b", "c", "d", "e", "f", "h", "i", "j", "k", "m", "n", "o", "p", "r", "s", "t", "w", "x", "y", "3", "4"]

### 추가적인 고려사항들

- 특정 문자 조합이 다른 문자처럼 보일 수 있음 (예: rn은 m처럼, 3은 w처럼 보일 수 있음)
  - ID 생성 단계에서 이런 조합을 피하는 것이 좋음  
- 발음이 유사한 문자도 피하는 것이 좋음 (예: b와 p)
  - 특히 ID가 구두로 전달되는 상황에서 중요

### 기존 사례들

- Crockford's Base32: 모호한 문자를 동일한 값으로 디코딩하고, 우연한 욕설도 고려함
- Open Location Code: 23456789CFGHJMPQRVWX 문자 세트 사용. 시각적 모호성 회피와 함께 일반적인 언어의 단어 형성도 피하고자 함. 단 6/G, 9/Q는 포함.

### GN⁺의 의견

- ID 생성에 있어 사용성과 가독성을 최우선으로 고려해야 함. 특히 ID가 구두로 전달되거나 손으로 기록되어야 하는 상황이 빈번하다면 더욱 그러함. 
- 시각적 모호성을 최소화할 수 있는 문자 세트를 선택하되, ID의 길이와 가능한 조합의 수 사이에서 적절한 절충점을 찾는 게 중요함. 
- 또한 서드파티 시스템과의 연동시 예상치 못한 이슈가 발생할 수 있으므로, 대소문자 구분 여부를 신중히 결정해야 함.
- ID 생성 로직에서 특정 문자 조합을 배제하거나, 발음이 유사한 문자를 피하는 등의 추가적인 고려도 필요함.
- Crockford's Base32나 Open Location Code 같은 사례를 참고해 프로젝트의 요구사항에 맞는 최적의 문자 세트를 설계하는 것이 바람직함.

## Comments



### Comment 33955

- Author: roxie
- Created: 2025-01-29T18:19:40+09:00
- Points: 1

이것도 좋아보여요 : https://stackoverflow.com/a/58098360/8556340

### Comment 33954

- Author: roxie
- Created: 2025-01-29T18:17:47+09:00
- Points: 1

발음까지 고려한건 정말 경이롭네요

### Comment 24651

- Author: neo
- Created: 2024-04-24T10:19:00+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=40127124) 
- 실제 현장에서 수백만 개의 장치에 모호한 문자를 포함한 시리얼 넘버를 사용해 고객 지원에 큰 어려움을 겪은 사례가 있음. 정규식으로 오타 변형을 생성하고 DB와 대조해 실제 시리얼 넘버를 추정하는 악몽 같은 경험을 함.
- 사용자에 따라 인코딩 방식을 다르게 해야 함. Base32는 명확한 문자 집합을 가지고 있어 적합하고, 구두로 전달할 때는 단어 목록 표현(예: "TIDE ITCH SLOW REIN RULE MOT")을 쓰는 게 좋음. 단, 관용구, 동음이의어, 방언 등의 함정이 도사리고 있으니 자체 단어 목록은 만들지 말 것.
- CPAN에 장난삼아 올린 임의 진법 연산 모듈(`Math::Fleximal`)로 인해 뜻밖의 지원 요청을 받은 적이 있음. 16진수를 영숫자 코드로 변환하는 데모 코드를 누군가 프로덕션에 사용한 것이 원인이었음.
- 닌텐도 스위치의 DLC 시리얼 넘버 입력 화면에서는 애매한 문자의 키를 비활성화해 UX를 개선함.
- 필기체로 적을 때 구별하기 어려운 문자도 피해야 함. 특히 '7'과 '1'은 혼동하기 쉬움.
- 대소문자를 모두 쓰면 대소문자 구분 없는 시스템이나 프로토콜에 의해 나중에 놀랄 수 있음. 사용자 편의성을 이유로 이를 버그라고 주장하지 않는 상용 시스템도 있음.
- 2FA 백업 코드를 종이에 적을 때마다 특정 문자(o/0, v/u, 5/S 등)에서 불안감이 엄습함. 이를 피하기 위해 문자에 장식을 더하곤 함.
- 와이파이 비밀번호로 3학년 아이도 철자를 정확히 쓸 수 있는 일상적인 단어("vacation")를 선택함.
- KeepassXC는 문자 종류(대문자, 소문자, 숫자, 기호 등)별로 색상을 달리해 가독성을 크게 높임.
- 비트코인 주소는 수정된 Base58 인코딩을 사용함.
- 글에서 Arial 폰트를 Ariel로 잘못 표기함.
