Published on

[django] Base62, Base32를 이용한 url Shortner만들기

Authors
  • avatar
    Name
    Almer Minified
    Twitter

URL shortner의 원리

URL shortner는 기존에 있는 url을 단축시킨다는 의미이다. 단축이라기보단 일대일 대응을 시켜서 어떤 값에 기존 url을 대입한다고 생각하면 된다. 그 원리로 사용되는 것이 base32나 base62, base64가 될 수 있다.

Base32, Base62, Base64는 모두 데이터를 인코딩하는 방법이다. 간단히 말하면 바이너리 데이터를 문자열 형태로 변환하여 텍스트 기반의 시스템에서 쉽게 사용할 수 있도록 하는 방법이다. 각각의 방법은 사용하는 문자의 집합이 다르다. 32, 62, 64는 사용되는 문자의 수이다.

base32

Base32 인코딩은 32개의 문자를 사용한다. 이들은 대개 26개의 대문자 알파벳(A-Z)과 6개의 숫자(2-7)를 이용한다. Base32 인코딩은 주로 사람이 읽고 이해하기 쉬운 형태의 인코딩을 요구할 때 사용된다. 주로 많이 쓰이는 단축url의 원리이다. 길지 않기 때문이다.

base62

Base62 인코딩은 62개의 문자를 사용한다. 26개의 소문자 알파벳(a-z), 26개의 대문자 알파벳(A-Z), 10개의 숫자(0-9)를 쓴다 이 Base62도 URL 단축 서비스에서 많이 사용된다. 이 인코딩은 URL에 사용될 수 있는 대부분의 안전한 문자들을 사용하기 때문이다.

base64

Base64 인코딩은 64개의 문자를 사용한다. 26개의 소문자 알파벳(a-z), 26개의 대문자 알파벳(A-Z), 10개의 숫자(0-9), 두 개의 추가 기호(+, /)를 쓴다. Base64는 바이너리 데이터를 ASCII 문자열로 변환하는 데 주로 쓴다. 출력 결과가 URL과 HTML에서 안전하지 않은 문자를 포함할 수 있어서 url 단축에는 추천하지 않는다.

그럼 이제 실제로 진행해보자

장고로 만들 것이다.

1. Django 모델

먼저 URL 단축 서비스에 필요한 Django 모델을 설정하자. 이 모델은 원본 URL과 인코딩된 단축 URL, 인덱스를 저장하는 데 사용될 것이다

from django.db import models

class TestShortenedURL(models.Model):
    url = models.URLField()
    encoded = models.CharField(max_length=15, blank=True, null=True)  # 단축 URL
    encoding_type = models.CharField(max_length=64, default='base62')  # 인코딩 타입 여기서는 base62 또는 base32

    def __str__(self):
        return self.encoded

2. 인코딩 함수 작성하기

Base62와 Base32 인코딩 함수를 작성하자. 여기서는 이미 제공된 Base62 인코딩 함수를 사용하고 참고로만 Base32 인코딩 함수 코드를 추가해놓겠다. 사용하진 않는다.

def base62(index):
    characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    result = ""
    while index > 0:
        result = characters[index % 62] + result
        index = index // 62
    return result

def base32(index):
    characters = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"  # Base32에는 I, O, U가 포함되지 않는다
    result = ""
    while index > 0:
        result = characters[index % 32] + result
        index = index // 32
    return result

3. URL 단축 함수

이 함수는 URL을 받아 DB에 저장하고 인코딩된 단축 URL을 리턴한다.

from .models import ShortenedURL

def generate_short_url(url, encoding_type='base62'):
    new_url = TestShortenedURL(url=url, encoding_type=encoding_type)
    new_url.save()  # URL 저장

    if encoding_type == 'base62':
        encoded_url = base62(new_url.id)
    elif encoding_type == 'base32':
        encoded_url = base32(new_url.id)
    else:
        raise ValueError("Unsupported encoding type")

    new_url.encoded = encoded_url
    new_url.save()  # 인코딩된 URL 업데이트

    return encoded_url

4. Django 뷰와 URL 설정하기

Django views.py에서 요청을 처리하고 단축된 URL을 Response로 주자.

from django.shortcuts import redirect
from .models import TestShortenedURL

def redirect_url(request, short_url):
    try:
        link = TestShortenedURL.objects.get(encoded=short_url)
        return redirect(link.url)
    except TestShortenedURL.DoesNotExist:
        return redirect('/error_page/')  # 오류 처리

그리고 urls.py에 라우팅을 추가

from django.urls import path
from . import views

urlpatterns = [
    path('<str:short_url>', views.redirect_url, name='redirect_url')
]

5. URL 단축 서비스 테스트하기

마지막으로 이 서비스를 테스트하여 모든 것이 제대로 작동하는지 확인하면 된다. 단축 URL을 생성하고 그 URL을 사용하여 원본 URL로 리디렉션되는지 확인해보자

단축 URL과 SEO

단축 url을 쓰면 SEO에 불리할 순 있다. 실제 검색엔진에 등록된 주소와 단축 URL의 형태가 달라서 이게 30x 로 리다이렉트 하는지 확인해야 검색엔진이 제대로 알 수 있기 때문이다.

그리고 redirection 을 할 때 301이냐 302이냐에 따라 또 결과가 다르다.

301 리디렉션

대부분의 단축 URL 서비스는 301 Moved Permanently 리디렉션을 사용하는 것 같다. 이는 검색 엔진에 원래 URL로 이동하라고 알려주어 SEO에 긍정적으로 작용할 수 있다. 301 리디렉션은 원래 페이지의 링크를 전달하여 페이지 랭크를 유지할 수 있도록 도와준다고 한다.

302 리디렉션 또는 307 리디렉션

일부 단축 URL 서비스는 302 Found 또는 307 Temporary Redirect를 사용할 수 있다. 이러한 일시적 리디렉션은 링크를 원본 URL로 전달하지 않는다고 한다. 그래서 SEO에 상대적으로 부정적인 영향을 미칠 수 있다.