URL 단축 서비스 개발 기획서
개발 계기
간단한 프로젝트를 해보고 싶었다. 무엇을 해볼지 고민하던 중에 URL 단축 서비스가 생각이 났다.
현재 나와있는 URL 단축 서비스는 영어 대소문자를 통해서 원본 URL을 단축시켜준다.
하지만 영어 알파벳은 총 26개이면서 대소문자를 포함하면 총 52개가 된다.
그러면 영어 한자리로 52개의 사이트가 단축이 되고, 5자리라고 했을 때 52 * 5로 260개의 사이트를 단축이 가능하다.
사용자가 많아지면 단축된 URL의 길이가 엄청 길어지기 때문에 URL을 단축시킨다는 의미가 없어진다고 생각한다.
그래서 생각해 본 것이 한글로 URL을 단축시킨다는 것이다.
한글은 한 글자로 총 초성 19개, 중성 21개, 종성 28개로 총 19 * 21 * 28로 11172개의 사이트를 단축할 수 있다.
그렇다면 5자리라고 했을 때는 11172 * 5로 55860개로 단축할 수 있다.
영어로 단축된 URL이 214자리라면 한국 URL은 한 글자로 표현이 가능하다는 점이다.
단축 알고리즘
URL을 단축하는 것은 데이터의 ID 값으로 진행하는 것으로 진행했다.
초성은 19개(0 ~ 18), 중성은 21개(0 ~ 20), 종성은 28개(0 ~ 27)이다.
int chosung = (int) (value % CHOSUNG_COUNT);
value /= CHOSUNG_COUNT;
int jungsung = (int) (value % JUNGSUNG_COUNT);
int jongsung = (int) (value / JUNGSUNG_COUNT);
char unicode = (char) (44032 + (chosung * JUNGSUNG_COUNT * JONGSUNG_COUNT) + (jungsung * JONGSUNG_COUNT) + jongsung);
예를 들어 ID가 1이면 1을 뺀 값인 0으로 한글로 변환된다.
초성 | 중성 | 종성 |
0 | 0 | 0 |
결과는 '가'이다.
ID가 20이라면 1을 뺀 19로 한글로 변환한다.
19는 초성 범위를 넘어서기 때문에 위의 식을 통해 중성이 1이 된다.
초성 | 중성 | 종성 |
0 | 1 | 0 |
결과는 '개'이다
원본 복원 알고리즘
변환된 한글을 ID로 다시 변환하여 해당 ID와 매핑된 원본 URL로 리다이렉트시켜준다.
private long hangulToId(String shortUrl) {
long id = 0;
for (int i = 0; i < shortUrl.length(); i++) {
char url = shortUrl.charAt(i);
String jamo = Normalizer.normalize(Character.toString(url), Form.NFD);
int chosungIndex = jamo.charAt(0) - 0x1100;
int jungsungIndex = jamo.charAt(1) - 0x1161;
int jongsungIndex = (jamo.length() > 2) ? jamo.charAt(2) - 0x11A7 : 0;
log.info("{}, {}, {}", chosungIndex, jungsungIndex, jongsungIndex);
id += chosungIndex + (CHOSUNG_COUNT * jungsungIndex) + (CHOSUNG_COUNT * JUNGSUNG_COUNT) * jongsungIndex + BASE * i;
}
return id + 1;
}
알고리즘에 대해 설명하자면 먼저 한글의 한 자리씩 가져와 자음과 모음을 분히해준다.
초성의 시작 유니코드가 `0x1100`이기 때문에 이를 빼면 현제 초성 인덱스를 확인할 수 있다.
이와 마찬가지로 중성과 종성도 각각 `0x1161`, `0x11A7`이 시작인덱스이다.
다만 종성은 있을 수도 있고 없을 수도 있기 때문에 종성이 존재할 때만 시작 유니코드를 빼주고 아니면 0으로 들어가게 했다.
이를 식을 통해 ID를 찾을 수 있도록 구현했다.