티스토리 뷰
문제 설명
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
다음과 같이 Encoding 을 한다.
- 우선 24비트 버퍼에 위쪽(MSB)부터 한 byte씩 3 byte의 문자를 집어넣는다.
- 버퍼의 위쪽부터 6비트씩 잘라 그 값을 읽고, 각각의 값을 아래 [표-1] 의 문자로 Encoding 한다.
입력으로 Base64 Encoding 된 String 이 주어졌을 때, 해당 String 을 Decoding 하여, 원문을 출력하는 프로그램을 작성하시오.
[제약사항]
문자열의 길이는 항상 4의 배수로 주어진다.
그리고 문자열의 길이는 100000을 넘지 않는다.
[입력]
입력은 첫 줄에 총 테스트 케이스의 개수 T가 온다.
다음 줄부터 각 테스트 케이스가 주어진다.
테스트 케이스는 Encoding 된 상태로 주어지는 문자열이다.
[출력]
테스트 케이스 t에 대한 결과는 “#t”을 찍고, 한 칸 띄고, 정답을 출력한다. (t는 테스트 케이스의 번호를 의미하며 1부터 시작한다.)
입력
10
TGlmZSBpdHNlbGYgaXMgYSBxdW90YXRpb24u
U3VzcGljaW9uIGZvbGxvd3MgY2xvc2Ugb24gbWlzdHJ1c3Qu
VG8gZG91YnQgaXMgc2FmZXIgdGhhbiB0byBiZSBzZWN1cmUu
T25seSB0aGUganVzdCBtYW4gZW5qb3lzIHBlYWNlIG9mIG1pbmQu
QSBmdWxsIGJlbGx5IGlzIHRoZSBtb3RoZXIgb2YgYWxsIGV2aWwu
…
출력
#1 Life itself is a quotation.
#2 Suspicion follows close on mistrust.
#3 To doubt is safer than to be secure.
#4 Only the just man enjoys peace of mind.
#5 A full belly is the mother of all evil.
...
풀이 과정
이 문제는 문제의 인코딩 내용을 제대로 이해해야만 풀 수 있는 문제입니다.
이해를 위해 문제가 설명하는 인코딩 방식을 첫 번째 입출력 예시를 가지고 직접 해보겠습니다.
- 우선 24비트 버퍼에 위쪽(MSB)부터 한 byte씩 3 byte의 문자를 집어넣는다.
- 버퍼의 위쪽부터 6비트씩 잘라 그 값을 읽고, 각각의 값을 아래 [표-1] 의 문자로 Encoding 한다.
그러니까, 예시 출력 1번 문장인 Life itself is a quotation. 을 가지고 위의 인코딩을 하면 TGlmZSBpdHNlbGYgaXMgYSBxdW90YXRpb24u 가 된다는 뜻입니다 !!!
1번의 ‘3 byte의 문자’ = 한 문자가 1 byte = 문자 3개 = “Lif”를 ‘24비트 버퍼’에 넣기 위해 1글자씩 아스키코드로 변환하고 이를 8비트의 2진수로 변환합니다. ‘L’, ‘i’, ‘f’를 아스키코드로 변환하면 76, 105, 102가 됩니다. 76을 2진수로 바꾸면 01001100, 01101001, 01100110가 됩니다. 이렇게 8비트씩 차지하는 3개의 이진수 010011000110100101100110가 24비트 버퍼에 들어갑니다.
그 다음은 2번 버퍼에 값을 6비트씩 자릅니다. 010011 / 000110 / 100101 / 100110 이 값을 문제의 표에 맞게 문자로 바꿉니다. 표의 값은 모두 10진수이니 이 값을 10진수로 변환해야 한다는 것을 알 수 있습니다. 010011 → 19 / 000110 → 6 / 100101 → 37 / 100110 → 38 19는 표에서 T, 6은 G, 37은 l, 38은 m → TGlm 이 값은 예시 출력 1번 문장의 앞의 4자리와 동일함을 알 수 있습니다.
이것이 문제가 말하는 ‘인코딩 방식’이고, 이 인코딩 과정을 거친 결과물이 입력으로 주어집니다. 우리는 이 결과물을 가지고 문제가 설명한 인코딩 방식을 반대로 하여 즉, 디코딩 해서 원문을 출력해야 합니다.
그렇다면 위의 과정을 전부 반대로 해서 디코딩 방식을 만들어 보겠습니다.
- 입력 문자 1개씩 [표-1]의 값으로 변환합니다.
- 1번의 값을 6비트의 2진수로 변환합니다.
- 모든 입력 문자를 확인할 때까지 1,2번을 반복해서 나오는 모든 6비트의 2진수를 하나로 이어 붙입니다.
- 이를 1 byte (= 8비트)씩 자르고 10진수로 변환해서 아스키코드 값을 알아냅니다. 이 아스키코드로 이루어진 문장이 인코딩 전의 문장입니다.
이 1~4번을 그대로 코드로 구현하면 정답입니다. 이를 도출해내는 것이 핵심입니다.
정답 코드
T = int(input())
# 여러개의 테스트 케이스가 주어지므로, 각각을 처리합니다.
for test_case in range(1, T + 1):
# 문제의 표를 딕셔너리로 만듦
# 디코딩에선 문자를 가지고 값을 알아야 하기 때문에 키를 문자, 밸류를 값으로 설정
encoding_dict = {
'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7,
'I': 8, 'J': 9, 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15,
'Q': 16, 'R': 17, 'S': 18, 'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23,
'Y': 24, 'Z': 25, 'a': 26, 'b': 27, 'c': 28, 'd': 29, 'e': 30, 'f': 31,
'g': 32, 'h': 33, 'i': 34, 'j': 35, 'k': 36, 'l': 37, 'm': 38, 'n': 39,
'o': 40, 'p': 41, 'q': 42, 'r': 43, 's': 44, 't': 45, 'u': 46, 'v': 47,
'w': 48, 'x': 49, 'y': 50, 'z': 51, '0': 52, '1': 53, '2': 54, '3': 55,
'4': 56, '5': 57, '6': 58, '7': 59, '8': 60, '9': 61, '+': 62, '/': 63
}
input_string = input()
binary_string = ""
# 3. 모든 입력 문자를 확인할 때까지 1,2번을 반복해서 나오는 모든 6비트의 2진수를 하나로 이어 붙입니다.
for letter in input_string:
# 1. 입력 문자 1개씩 [표-1]의 값으로 변환합니다.
# 2. 1번의 값을 6비트의 2진수로 변환합니다.
binary = format(encoding_dict[letter], '06b')
binary_string += str(binary)
answer = ""
for i in range(0, len(binary_string), 8):
# 4. 8비트씩 자르고(-> 문자열 슬라이싱) 10진수로 변환해서
bin = int(binary_string[i:i+8], 2)
# 4. 아스키코드 값을 알아냅니다.
ascii = chr(bin)
answer += ascii
# 이 아스키코드로 이루어진 문장이 인코딩 전의 문장입니다.
print("#%d %s" %(test_case, answer))
- 10진수를 6자리 2진수로 바꾸는 방법: format 함수 사용 → format(10진수 값, '06b')
- '06b' → 2진수(b)로 변환하되, (6)자리로 맞추면서 부족한 자리는 앞에 (0)으로 채운다.
- 그럼 8자리 2진수로 바꾸는 경우에는? → ‘08b’
- 10진수를 아스키코드로 바꾸는 방법: chr 함수 사용 → chr(10진수 값)
- chr(65) → ‘A’
새로 배운 게 많았던 문제였습니다.
이상입니다.
'Algorithm' 카테고리의 다른 글
백준 10026번: 적록색약 (G5) - Python 풀이 (0) | 2025.04.30 |
---|---|
백준 1260번: DFS와 BFS (S2) - Python 풀이 (0) | 2025.04.29 |
SWEA 1926번: 간단한 369게임 (D2) - Python 풀이 (1) | 2025.04.25 |
SWEA 2001번: 파리 퇴치 (D2) - Python 풀이 (feat. 달팽이의 저주) (1) | 2025.04.23 |
SWEA 1204번: 최빈수 구하기 (D2) - Python 풀이 (0) | 2025.04.23 |
- Total
- Today
- Yesterday
- Swift
- 코테준비
- 큐
- 백트래킹
- Python
- Swift로백준풀기
- 정렬
- 이분탐색
- swea
- ios
- 프로그래머스
- 알고리즘
- Programmers
- SQL
- Baekjoon
- 투포인터
- MySQL
- 우선순위큐
- 백준
- 구현
- ios앱개발
- BFS
- dp
- 그리디
- 자료구조
- 코테
- 힙
- 코딩테스트
- 스택
- 다이나믹프로그래밍
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |