본문 바로가기
알고리즘/Samsung

SW 1928. Base64 Decoder

by son_i 2023. 5. 5.
728x90

SW Expert Academy

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

자바

이거는 문제를 이해하는 것부터 정말 오래걸렸다 ....

 

Base64 == 64진법

<Base64 Encoding>

1. 원본 문자열 3byte를 아스키코드로 변환해서 24비트 버퍼에 넣는다.

2. 6비트씩 끊어서 Base64 테이블의 문자로 변환.

\

<Base64 Decoding>

1. 디코딩된 문자열의 4byte를 Base64테이블을 보고 변환해서 24비트 버퍼에 넣는다.

2. 8비트씩 끊어서 아스키코드표의 문자로 변환.

 

이해하고 나면 이렇게 간단한디 ...

 

작업

- 인코딩되니 문자열을 Base64값으로 변환해서 arr이라는 ArrayList 제일 뒤에 계속해서 넣음.

  뒤에서부터 넣은 이유는 그래야 순서대로 넣어지니까. 뭐 그때 반복문 안의 변수 j로 해도 되겠었다.

 

- 2진수로 바꿔서 6비트씩 저장.

  n이라는 변수 반복문 밖에 선언 -> 한 문자를 2진수로바꾸면 6자리가 되고(0~5인덱스) 그 다음 문자는 인덱스 6부터 저장되어야하니까 그걸 연산하기 위해서 만듦.

반복을 돌면서 맨 앞자리 숫자부터 2로 나눈 값이 1이상이다 => 2진수로 바꿀 수 arr.get(m)이 다 나눠진 거임.

   list라는 ArrayList에 0+n번째에 arr.get(m)을 2로 나눈 나머지를 위에서부터 넣기 시작함.

   arr.set(m,arr.get(m)/2); //원본arr의 m번째 값을 2로 나눈 몫값으로 다시 세팅 ch 증가

ch는 arr.get(m)을 2로 나눈 나머지, 2로 나눈 몫을 다 list에 넣었을 때 몇 자리까지 차지하는 지를 헤아리는 변수

얘가 6이 아니라면 앞에서부터 0을 또 채워서 6자리를 만들어줘야함.

 

- 8자리씩 끊어서 아스키 코드로 변환.

num += (list.get(j*9)+ch)*Math.pow(2,7-ch);

이 작업 반복을 끝내고 num을 (char)로 출력하면 아스키 코드 문자 값이 나옴.

 

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

/*
   사용하는 클래스명이 Solution 이어야 하므로, 가급적 Solution.java 를 사용할 것을 권장합니다.
   이러한 상황에서도 동일하게 java Solution 명령으로 프로그램을 수행해볼 수 있습니다.
 */
public class Solution
{
	public static void main(String args[]) throws Exception
	{
		//System.setIn(new FileInputStream("C:\\so_Project\\workspace\\BaekJoon\\src\\algorithm\\input.txt"));

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		int T = Integer.parseInt(br.readLine()); //테스트 케이스
		
		StringBuilder sb = new StringBuilder();
		for(int i=1;i<=T;i++) { //하나의 테스트케이스마다 반복
			sb.append("#"+i+" ");
			String str = br.readLine();
			List <Integer>arr = new ArrayList<>(); 
			List <Integer>list = new ArrayList<>(); 

			for(int j=0;j<str.length();j++) { //인코딩 문자열 Base 64 변환
				char c = str.charAt(j);
				
				if(c >='A' && c<='Z') {
					arr.add(arr.size(),c-65);
				}
				else if(c>= 'a' && c<='z') {
					arr.add(arr.size(),c-71);
				}
				else {
					if( c>= '0' && c<= '9') {
						arr.add(arr.size(),c+4);
					}
					else if (c =='+') arr.add(arr.size(),62);
					else arr.add(arr.size(),63);
				}				
			}
			//2진수 6비트씩 저장
			int n=0;
			for(int m=0;m<arr.size();m++) {
				int ch =0;
				while(arr.get(m)/2 >1) {
					list.add(0+n,arr.get(m)%2);
					arr.set(m,arr.get(m)/2);
					ch++;
				}
				list.add(0+n,arr.get(m)%2);
				list.add(0+n,arr.get(m)/2);
				ch+=2;
				while(ch !=6) {
					list.add(0+n,0);
					ch++;
				}
				n+=6;
			}
			//8자리씩 끊어서 아스키 코드표로 변환
			for(int j=0;j<list.size()/8;j++) {
				int num = 0;
				int ch =0;
				while(ch != 8) {
					num += (int)(list.get((j*8)+ch)*Math.pow(2, 7-ch));
					ch++;
				}
				sb.append((char)num);
			}sb.append("\n");
		}//하나의 테스트 케이스 끝 
		System.out.println(sb);
	}
}

 

 

'알고리즘 > Samsung' 카테고리의 다른 글

SW 14413. 격자판 칠하기 (BFS)  (1) 2023.05.14
SW 1288. 새로운 불면증 치료법  (0) 2023.05.05
SW 1940. 가랏! RC카 !  (0) 2023.05.05
SW 1285. 아름이의 돌 던지기  (0) 2023.05.05
SW 1945. 간단한 소인수분해  (0) 2023.05.02