[SW Expert Academy] 1928. Base64 Decoder

코코·2023년 10월 17일

알고리즘

목록 보기
1/21
post-thumbnail

✅ 난이도

D2

✅ 문제

다음과 같이 Encoding 을 한다.

  1. 우선 24비트 버퍼에 위쪽(MSB)부터 한 byte씩 3 byte의 문자를 집어넣는다.

  2. 버퍼의 위쪽부터 6비트씩 잘라 그 값을 읽고, 각각의 값을 아래의 문자로 Encoding 한다.

입력으로 Base64 Encoding 된 String 이 주어졌을 때, 해당 String 을 Decoding 하여, 원문을 출력하는 프로그램을 작성하시오.

[제약사항]
문자열의 길이는 항상 4의 배수로 주어진다.
그리고 문자열의 길이는 100000을 넘지 않는다.

✅ 개념

  • Base64 인코딩
    바이너리 데이터를 ASCII 문자열로 변환하는 방법
    1) 이진 데이터를 6bit로 분할
    2) 각 6bit 그룹을 10진수로 변환
    3) 해당 10진수를 Base64 문자로 매핑
    +) 데이터의 길이가 3의 배수가 아니면 패딩 문자 =를 추가
  • Base64 디코딩
    문자열을 원래의 바이너리 데이터로 변환하는 방법
    1) Base64 문자를 해당하는 10진수로 변환
    2) 10진수를 2진수로 변환
  • 10진수 -> 2진수 변환
    bin() 함수 사용
    '0b'의 접두사를 제거하기 위해 [2:] 슬라이싱 사용하기
  • 10진수 -> 바이트 바로 변환
    bytes() 함수 사용하기

✅ 풀이

  1. 인코딩으로 들어온 Base64문자열을 10진수로 변환
  2. 해당 10진수를 2진수로 변환
    2진수로 변환 시, 6bit가 되지 않으면 0으로 채워줘야 함
  3. 2진수를 바이너리 데이터로 변환
    3-1. 2진수가 담겨있는 string을 8bit 단위로 나눠서 반복문 실행
    3-2. 2진수 문자열을 정수로 변환
    3-3. 정수를 바이너리 데이터로 변환 (bytes() 사용)
  4. 바이너리 데이터를 문자 인코딩으로 해석해서 출력 (utf-8 사용)

✅ 코드

라이브러리 O 코드

SWEA에는 base64 라이브러리 사용이 막혀 있다.

from base64 import b64decode

T = int(input())
encode_list = []

for _ in range(T):
    encode_string = input()
    encode_list.append(encode_string)

for t, encode_string in enumerate(encode_list, start=1):
    print("#", t, end=" ")
    decode_string = base64.b64decode(encode_string.encode('utf-8'))
    decode_string = decode_string.decode('utf-8')
    print(decode_string)

라이브러리 X 코드

T = int(input())
encode_list = []

decode = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
          'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
          '0','1','2','3','4','5','6','7','8','9','+','/']

for _ in range(T):
    encode_string = input()
    encode_list.append(encode_string)

for t, encode_string in enumerate(encode_list, start=1):
    print("#"+str(t), end=" ")
    decode_string = ""
    # 1. base64 문자열 -> 10진수
    for c, char in enumerate(encode_string, start=0):
        index = decode.index(char)
        # 2. 10진수 -> 이진수 변환
        binary = bin(index)[2:]
        if len(binary)<6:
            binary = "0"*(6-len(binary)) + binary
        decode_string += binary
    # 3. 이진수 -> 바이트 전환
    decode_string = bytes([int(decode_string[j:j+8], 2) for j in range(0, len(decode_string), 8)])
    decoded_text = decode_string.decode('utf-8')
    # 4. 출력
    print(decoded_text)
    

0개의 댓글