티스토리 뷰

Developer

How to make shorten url using BASE62

rocksea 2016. 5. 19. 19:06

How to make shorten url using BASE62.

짧은 URL을 만들기 위한 알고리즘을 고민하던 중. base64를 고민해봤는데, 보통의 Short URL들의 특징을 살펴보니 특수문자를 제외한 영문 대소문자 + 숫자로만 이루어진 조합의 URL을 사용하고 있다.  특수문자가 사용될 경우 URL Encoding을 해줘야 하기때문에  (Base64의  +의 경우  %2D, /의 경우 %2F, 패딩 '='은 %03D) 특수 문자를 제외한 나머지 62개의 값을 가지고 URL을 생성을 목적으로 하는게 Base62의 기본 알고리즘이다. 

기본적으로  Base64의 알고리즘을 알 필요가 있다.

Base64는 8비트로 구성된 입력값을 2의 6승인 6비트씩 짤라서 64까지의 값을 표현 한다.

ASCII Code 입력 값 : CBA 인코딩

 01000011

 01000010

 01000001

 

 010000

 110100

 001001

 000001

 Q

 0

 J

 B

Base64 Encoding 결과 값 : Q0JB


Base62의 경우에는 +,/ 문자를 제외한 62개의 값을 표현한다.

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789


특정 sequence를 매칭하여 BASE62 주소로 반환하는 코드를 작성해보았다. 

int형과 long 타입까지 생성 가능하도록 작성 하였다.

Base62.java

/**
 * Created by rocksea on 2016. 5. 12.
 */
public class Base62 {
    /**
     * Base62 Character Table
     */
    static final char[] BASE62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray();

    /**
     * Base62 Encoding
     *
     * @return the base 62 string of an integer
     */
    public static String encode(int value) {
        final StringBuilder sb = new StringBuilder();
        do {
            int i = value % 62;
            sb.append(BASE62[i]);
            value /= 62;
        } while (value > 0);
        return sb.toString();
    }

    public static String encodeToLong(long value) {
        final StringBuilder sb = new StringBuilder();
        do {
            int i = (int)(value % 62);
            sb.append(BASE62[i]);
            value /= 62;
        } while (value > 0);
        return sb.toString();
    }

    /**
     * Returns the base 62 value of a string.
     *
     * @return the base 62 value of a string.
     */
    public static int decode(String value) {
        int result=0;
        int power=1;
        for (int i = 0; i < value.length(); i++) {
            int digit = new String(BASE62).indexOf(value.charAt(i));
            result += digit * power;
            power *= 62;
        }
        return result;
    }

    public static long decodeToLong(String value) {
        long result=0;
        long power=1;
        for (int i = 0; i < value.length(); i++) {
            int digit = new String(BASE62).indexOf(value.charAt(i));
            result += digit * power;
            power *= 62;
        }
        return result;
    }
}


Base62Test.java

import org.junit.Test;
import java.util.Random;
import static junit.framework.Assert.assertEquals;

public class Base62Test {

    @Test
    public void testEncodeAndDecode() throws Exception{
        String encodedReservationNo = Base62.encodeToLong(1234512345);
        System.out.println("ENCODE : "+encodedReservationNo+", DECODE : " + Base62.decodeToLong(encodedReservationNo));
        assertEquals(1234512345, Base62.decodeToLong(encodedReservationNo));
    }

    @Test
    public void testRandomEncodeAndDecode() throws Exception{
        for(int i=0; i < 10; i++) {
            Random rnd = new Random();
            long value = Math.abs(rnd.nextLong() % 10000000000L);
            System.out.println("VALUE : " + value);
            String encodedReservationNo = Base62.encodeToLong(value);
            System.out.println("ORIGINAL : " + value + ", ENCODE : " + encodedReservationNo + ", DECODE : " + Base62.decodeToLong(encodedReservationNo));
            assertEquals(value, Base62.decodeToLong(encodedReservationNo));
        }
    }
}

SMS나 메세지, SNS URL 공유가 많이 필요한 서비스에 활용할 경우 유용하다.

'Developer' 카테고리의 다른 글

LRU Cache Algorithm  (0) 2016.10.13
[Jenkins] how to install jenkins on docker  (0) 2016.08.04
[Heroku] Getting started with Heroku  (0) 2016.05.09
[gradle] How To Speed up Gradle build time  (0) 2016.04.27
[Algorithm] Euclidean Algorithm in python  (0) 2016.03.31
댓글