블로그 목록으로

단축 코드는 어떻게 만들어지나요

순번 방식과 무작위 방식의 차이, Base58 문자 집합이 헷갈리는 글자를 빼는 이유, 7자리가 만드는 거대한 조합 수, 그리고 드물게 일어나는 충돌을 처리하는 방법을 정리합니다.

linkpado.com/xY3kP9q에서 xY3kP9q 부분, 즉 단축 코드는 어떻게 정해질까요. 그냥 아무 글자나 붙이는 것처럼 보이지만, 이 짧은 문자열을 만드는 방식에는 예측 가능성, 서버 간 조율, 충돌 처리 같은 여러 결정이 숨어 있습니다. 이 글은 linkpado가 코드를 만드는 방식을 하나씩 따라가며 설명합니다.

순번으로 셀까, 무작위로 뽑을까

코드를 만드는 방법은 크게 두 갈래로 나뉩니다.

순번 방식은 링크를 만들 때마다 1, 2, 3… 으로 번호를 매기고, 그 숫자를 짧은 문자로 바꿉니다. 구현이 단순하고 코드가 절대 겹치지 않는다는 장점이 있습니다. 하지만 두 가지 문제가 따라옵니다.

첫째, 다음 링크를 추측할 수 있습니다. 누군가 linkpado.com/0001을 받았다면 0002, 0003도 시도해 볼 수 있고, 그러면 남이 만든 링크의 목적지가 들여다보입니다. 또 지금까지 몇 개의 링크가 만들어졌는지도 번호만 보고 짐작됩니다.

둘째, 여러 서버가 번호를 맞춰야 합니다. 분산 환경에서는 서버 여러 대가 동시에 링크를 만드는데, 모두가 같은 "다음 번호"를 공유하려면 중앙 카운터나 잠금 같은 동기화 장치가 필요합니다. 이 조율은 트래픽이 늘수록 병목이 됩니다.

무작위 방식은 정해진 문자 집합에서 매번 몇 글자를 무작위로 뽑습니다. 번호를 세지 않으니 다음 링크를 추측하기 어렵고, 서버끼리 "다음 차례"를 맞출 필요도 없습니다. 각 서버가 알아서 뽑고, 혹시 겹치는 경우만 처리하면 됩니다. linkpado는 이 무작위 방식을 씁니다.

Base58: 왜 일부 글자를 빼나

무작위로 뽑는다면 어떤 글자들 중에서 뽑을지를 정해야 합니다. linkpado는 Base58 문자 집합을 씁니다. 이름 그대로 58개의 글자로 이루어져 있는데, 영문 대문자·소문자·숫자 전체(62자)에서 헷갈리기 쉬운 네 글자를 일부러 뺀 것입니다.

빠지는 글자는 다음과 같습니다.

  • 숫자 0과 대문자 O — 모양이 거의 같습니다.
  • 숫자 1, 소문자 l, 대문자 I — 글꼴에 따라 구별이 안 됩니다.

이 글자들을 빼는 이유는 사람이 코드를 눈으로 읽고 옮길 때를 위해서입니다. 코드를 종이에 적거나, 전화로 불러 주거나, 화면을 보고 따라 입력하는 상황을 떠올려 보세요. l1이 섞인 코드는 잘못 입력되기 쉽고, 한 글자만 틀려도 엉뚱한 곳으로 가거나 아예 열리지 않습니다. Base58은 이런 실수가 일어날 여지를 처음부터 줄여 둡니다. 같은 이유로 Base58은 비트코인 주소 같은 곳에서도 오래 쓰여 왔습니다.

7자리면 얼마나 많은 조합이 나오나

linkpado의 기본 코드는 7자리입니다. 한 자리마다 58가지 중 하나가 올 수 있으니, 전체 조합 수는 58을 일곱 번 곱한 값입니다.

58 × 58 × 58 × 58 × 58 × 58 × 58 ≈ 2,207,984,167,552

2조 개가 넘습니다. 이 숫자가 왜 중요할까요. 코드를 무작위로 뽑으면 이론적으로는 이미 쓰인 코드가 다시 나올 수 있는데, 가능한 코드가 이렇게 많으면 그럴 확률이 아주 낮아지기 때문입니다. 수백만 개의 링크가 이미 만들어진 상태에서도, 새로 뽑은 7자리가 그중 하나와 겹칠 가능성은 매우 작습니다. 공간이 충분히 넓으면 굳이 순번처럼 "겹치지 않음"을 보장하지 않아도, 실제로는 거의 겹치지 않습니다.

드물게 겹치면 어떻게 되나

"거의" 겹치지 않는다는 말은 아주 가끔은 겹칠 수 있다는 뜻이기도 합니다. linkpado는 이 드문 경우를 다음과 같이 처리합니다.

코드는 데이터베이스에 유일 키(unique key) 로 저장됩니다. 같은 코드를 두 번 저장하려고 하면 데이터베이스가 이를 거부합니다. 그래서 새 코드를 저장하다가 거부당하면, 그것은 그 코드가 이미 쓰이고 있다는 신호입니다. 이때 서비스는 새 코드를 다시 뽑아 저장을 다시 시도합니다. 이 재시도는 몇 차례로 제한됩니다.

이 방식의 좋은 점은, 코드를 만들기 전에 미리 확인하거나 서버끼리 조율할 필요가 없다는 것입니다. 그냥 뽑아서 저장을 시도하고, 거부당할 때만 다시 뽑으면 됩니다. 충돌이 워낙 드물기 때문에 이 재시도는 거의 일어나지 않고, 일어나더라도 보통 한 번 다시 뽑는 것으로 끝납니다.

왜 안전한 무작위가 중요한가

마지막 조각은 "무작위"를 어떻게 만드느냐입니다. linkpado는 코드를 암호학적으로 안전한 난수 생성기로 뽑습니다. 일반적인 난수와 달리, 이런 난수는 지금까지 나온 값을 보고 다음 값을 예측하기가 사실상 불가능하도록 설계되어 있습니다.

이 점이 코드에서는 곧 안전성으로 이어집니다. 누군가 자신이 받은 링크 xY3kP9q를 보고 다른 사람의 링크를 알아내려 해도, 다음에 어떤 코드가 나올지 추측할 단서가 없습니다. 순번 방식이라면 인접한 번호를 시도해 볼 수 있지만, 안전한 난수로 2조 개의 공간에서 뽑힌 코드는 일일이 찍어 맞히기에는 경우의 수가 너무 많습니다.

정리하면, linkpado의 코드 하나에는 네 가지 결정이 함께 담겨 있습니다. 추측을 막는 무작위 방식, 사람이 읽기 쉽도록 헷갈리는 글자를 뺀 Base58, 충돌을 드물게 만드는 넉넉한 7자리 공간, 그리고 그 안에서 안전하게 코드를 뽑는 난수 생성기입니다. 평소에는 신경 쓸 필요가 없지만, 짧은 주소 하나가 이렇게 만들어집니다. 더 읽기 좋은 경로가 필요하다면 Pro에서 소문자·숫자·하이픈으로 된 3~32자 커스텀 경로를 직접 정할 수도 있습니다. 직접 링크를 만들어 보고 싶다면 홈에서 바로 시도해 볼 수 있습니다.