Home Base64 Principle
Post
Cancel

Base64 Principle

드림핵 문제 like64 문제를 풀다 궁금했던 부분을 알아봅시다.
Base64 encoding & Decoding 원리를 알아봅시다.

What is Base64

Base64는 ascii 영역의 문자들로 이루어진 문자열로 변환하는 인코딩 기술입니다.
전체의 ascii 영역은 아니며 2^6 -> 64글자를 가지고 인코딩을 하는 방법입니다.

어떤 방식으로 인코딩과 디코딩이 이루어 지는지 알아봅시다.

Encoding & Decoding

python으로 간단한 문자열을 인코딩 및 복호화를 사용하는 방식입니다.
base64를 import 하여 간단하게 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import base64

text = "glasses96"
print(f"[+] Plain text : {text}")
#[+] Plain text : glasses96

text = text.encode('utf-8')
encoding_text = base64.b64encode(text).decode('utf-8')
print(f"[+] Encoding text : {encoding_text}")
#[+] Encoding text : Z2xhc3Nlczk2

decoding_text = base64.b64decode(encoding_text).decode('utf-8')
print(f"[+] Decoding text : {decoding_text}")
#[+] Decoding text : glasses96

Encoding Principle

인코딩은 어떤방법으로 할 수 있는지 알아봅시다.
테스트는 간단히 AB를 인코딩 하는 방법입니다.

  1. 인코딩에 사용할 문자열 셋(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/)
    -> 64개(2^6)의 문자
  2. 문자열을 전부 8비트 2진수로 변환
    -> ex) A => 01000001, B => 01000010
  3. 6비트 씩 묶음
    -> 010000 010100 0010
  4. 6비트가 안되면 0 padding을 추가
    -> 010000 010100 001000
  5. 16, 20, 8로 문자열의 셋의 인덱스로(8,16,8) 사용 -> QUI
  6. 패딩을 표현하기 위해 “=” 를 추가
    -> QUI=

AB를 파이썬 코드에 넣었을때 똑같이 나오는 것을 확인할 수 있습니다.

1
2
[+] Plain text : AB
[+] Encoding text : QUI=

Base64 Encoding Code

파이썬 코드로 만든 base64 인코딩 함수입니다.
위에서 설명한거처럼 8비트에서 6비트로 쪼개서 문자열 셋에 인덱스로 가져오고 6비트가 안되면 0 패딩을 채웁니다.
패딩 문자열 “=” 을 추가하는데 여기서 “=”의 개수를 몇개를 넣어야 하는지를 보면 2진수로 변환된 문자열의 길이를 24로 나눈 나머지를 구합니다.
그리고 24 - 나머지를 하고 다시 6으로 나눈 몫 만큼 "=" 를 추가합니다.

24를 나누는 이유는 8비트와 6비트를 사용하기 떄문에 최소 공배수인 24를 사용하고, base64에선 6비트를 1글자로 하기 때문에 6으로 나눈 몫의 값을 =을 추가합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def custom_base64_encode(text):
    # Base64 인코딩에 사용되는 문자셋
    base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

    # 입력 문자열을 바이트로 변환
    binary_data = text.encode('utf-8')
    
    # 바이트를 이진수로 변환
    binary_string = ''.join(format(byte, '08b') for byte in binary_data)

    # 6비트씩 묶어서 Base64 문자로 매핑
    encoded_chars = []
    for i in range(0, len(binary_string), 6):
        chunk = binary_string[i:i+6]
        padding = 6 - len(chunk)
        chunk = chunk + '0' * padding
        decimal_value = int(chunk, 2)
        encoded_chars.append(base64_chars[decimal_value])

    # padding 문자 추가
    padding = len(binary_string) % 24
    if padding > 0:
        padding = 24 - padding
        encoded_chars.extend(['='] * (padding // 6))

    # 리스트를 문자열로 변환하여 반환
    return ''.join(encoded_chars)

결과를 보면 똑같은 것을 확인할 수 있습니다.

1
2
3
4
5
6
7
original_text = "glasses96"
encoded_text = custom_base64_encode(original_text)

print("Original Text:", original_text)
#Original Text: glasses96
print("Encoded Text:", encoded_text)
#Encoded Text: Z2xhc3Nlczk2

Decoding Principle

복호화도 알아봅시다.

  1. 인코딩된 문자열을 6비트로 2진수로 변환
    -> ex) QWI= -> 010000010100001000
  2. ”=” 문자 개수 만큼 “000000”을 붙여줌
    -> 010000010100001000000000
  3. 8비트 문자열로 변환
    -> AB

Base64 Decoding Code

파이썬 코드로 만든 base64 디코딩 함수입니다. 인코딩된 문자열을 base64 문자열 셋과 매핑하여 6비트 2진수 값을 이어붙입니다.
= 갯수만큼 000000으로 추가해줍니다.
마지막으로 8비트로 문자열로 바꿔줘 원래의 문자열을 보여줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def custom_base64_decode(encoded_text):
    # Base64 디코딩에 사용되는 문자셋
    base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

    # '='를 제거하고 Base64 문자를 이진수로 매핑
    binary_string = ''
    for char in encoded_text:
        if char == '=':
            binary_string += "000000"
        else:
            decimal_value = base64_chars.index(char)
            binary_string += format(decimal_value, '06b')

    # 이진수를 바이트로 변환하여 반환
    return int(binary_string, 2).to_bytes(len(binary_string) // 8, byteorder='big').decode('utf-8')

결과를 보면 잘 디코딩 된것을 알 수 있습니다.

1
2
3
4
5
6
7
8
9
10
original_text = "glasses96"
encoded_text = custom_base64_encode(original_text)
decoded_text = custom_base64_decode(encoded_text)

print("Original Text:", original_text)
#Original Text: glasses96
print("Encoded Text:", encoded_text)
#Encoded Text: Z2xhc3Nlczk2
print("Decoded Text:", decoded_text)
#Decoded Text: glasses96

후기

base64 인/디코딩 원리를 배우니 재밌었습니다! 끝.