Base64는 문자를 비트(8비트)로 바꾼 후, 6비트씩 나눠서 다시 표현한다.
예를 들어 abc 라면 ...
ASCII 코드값 a(97) b(98) c(99)
a
0 1 1 0 0 0 0 1
b
0 1 1 0 0 0 1 0
c
0 1 1 0 0 0 1 1
0 1 1 0 0 0 0 1 / 0 1 1 0 0 0 1 0 / 0 1 1 0 0 0 1 1
이렇게 abc가 된다.
이것을 6비트씩 다시 묶어보면
0 1 1 0 0 0 / 0 1 0 1 1 0 / 0 0 1 0 0 1 / 1 0 0 0 1 1
이렇게 묶은 값으로 base64 table 을 참고하여 변환한다. 이 테이블은 공식적으로 지정되어 있어 어느 application에서건 같은 값을 출력해준다.
abc -- base64 encoding --> YWJj
Base58은 왜 사용할까?
기존 base64 에는 사람 눈으로 착각할 수 있는
숫자 0과 영문 대문자 O
영문 대문자 I와 영문 소문자 l
그리고, 더블클릭 했을 때 전체 셀렉트를 방해하는 캐릭터가 존재한다. (+, /, =)
이를 제외시킨 base58은 base64와 다른 테이블을 갖고 있다.
그런데... 공식적인 테이블이 정해지지 않아서 application 마다 다른 값을 출력할 수 있다.
프로그래밍을 할 때는, 동일한 테이블 표를 사용해야 정상적으로 encoding/decoding이 된다.
맨 앞에 Version byte 가 들어가고, 맨 뒤에는 오류 감지를 위한 체크섬 4byte 가 들어간다.
Golang을 예로 들면,
const version byte = '1'
str := "Test string."
// Encode
// 이와 같이 version이 필요하다.
eStr := base58.CheckEncode([]byte(str), version)
// Decode
// 리턴값으로 version 값이 나온다.
bd, ver, err := base58.CheckDecode(eStr)
// exception handling ~ ...
fmt.Println(string(bd) // Test string.
비트코인에서는 주소의 경우에 Version byte를 0으로, 개인키의 경우는 128로 설정되어 있다고 한다.
이와 같이 Version byte 로 구분해서 관리 할 수 있겠다.