[SWEA] D2 - 1928๋ฒˆ | Base64 Decoder

EllievVยท2024๋…„ 11์›” 14์ผ

๐ŸŠ CodingTest

๋ชฉ๋ก ๋ณด๊ธฐ
13/18

๐Ÿ” ๋ฌธ์ œ ๋ณด๋Ÿฌ ๊ฐ€๊ธฐ

์ž…๋ ฅ์œผ๋กœ Base64 Encoding ๋œ String ์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, ํ•ด๋‹น String ์„ Decoding ํ•˜์—ฌ, ์›๋ฌธ์„ ์ถœ๋ ฅํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

<์ธ์ฝ”๋”ฉ ๊ณผ์ •>

STEP 1. ์šฐ์„  24๋น„ํŠธ ๋ฒ„ํผ์— ์œ„์ชฝ(MSB)๋ถ€ํ„ฐ ํ•œ byte์”ฉ 3 byte์˜ ๋ฌธ์ž๋ฅผ ์ง‘์–ด๋„ฃ๋Š”๋‹ค.

STEP 2.๋ฒ„ํผ์˜ ์œ„์ชฝ๋ถ€ํ„ฐ 6๋น„ํŠธ์”ฉ ์ž˜๋ผ ๊ทธ ๊ฐ’์„ ์ฝ๊ณ , ๊ฐ๊ฐ์˜ ๊ฐ’์„ ์•„๋ž˜ [ํ‘œ-1] ์˜ ๋ฌธ์ž๋กœ Encoding ํ•œ๋‹ค.

STEP 3.์ž…๋ ฅ์œผ๋กœ Base64 Encoding ๋œ String ์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, ํ•ด๋‹น String ์„ Decoding ํ•˜์—ฌ, ์›๋ฌธ์„ ์ถœ๋ ฅํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

๋ฌธ์ œ ์ƒ์„ธ ์„ค๋ช…

๋‹ค์Œ๊ณผ ๊ฐ™์ด Encoding ์„ ํ•œ๋‹ค.

  1. ์šฐ์„  24๋น„ํŠธ ๋ฒ„ํผ์— ์œ„์ชฝ(MSB)๋ถ€ํ„ฐ ํ•œ byte์”ฉ 3 byte์˜ ๋ฌธ์ž๋ฅผ ์ง‘์–ด๋„ฃ๋Š”๋‹ค.

  2. ๋ฒ„ํผ์˜ ์œ„์ชฝ๋ถ€ํ„ฐ 6๋น„ํŠธ์”ฉ ์ž˜๋ผ ๊ทธ ๊ฐ’์„ ์ฝ๊ณ , ๊ฐ๊ฐ์˜ ๊ฐ’์„ ์•„๋ž˜ [ํ‘œ-1] ์˜ ๋ฌธ์ž๋กœ Encoding ํ•œ๋‹ค.

์ž…๋ ฅ์œผ๋กœ Base64 Encoding ๋œ String ์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, ํ•ด๋‹น String ์„ Decoding ํ•˜์—ฌ, ์›๋ฌธ์„ ์ถœ๋ ฅํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

[์ œ์•ฝ์‚ฌํ•ญ]
๋ฌธ์ž์—ด์˜ ๊ธธ์ด๋Š” ํ•ญ์ƒ 4์˜ ๋ฐฐ์ˆ˜๋กœ ์ฃผ์–ด์ง„๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๋ฌธ์ž์—ด์˜ ๊ธธ์ด๋Š” 100000์„ ๋„˜์ง€ ์•Š๋Š”๋‹ค.

[์ž…๋ ฅ]
์ž…๋ ฅ์€ ์ฒซ ์ค„์— ์ด ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ๊ฐœ์ˆ˜ T๊ฐ€ ์˜จ๋‹ค.
๋‹ค์Œ ์ค„๋ถ€ํ„ฐ ๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์ฃผ์–ด์ง„๋‹ค.
ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋Š” Encoding ๋œ ์ƒํƒœ๋กœ ์ฃผ์–ด์ง€๋Š” ๋ฌธ์ž์—ด์ด๋‹ค.

[์ถœ๋ ฅ]
ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค t์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋Š” โ€œ#tโ€์„ ์ฐ๊ณ , ํ•œ ์นธ ๋„๊ณ , ์ •๋‹ต์„ ์ถœ๋ ฅํ•œ๋‹ค.
(t๋Š” ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ๋ฒˆํ˜ธ๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค.)

์ž…๋ ฅ์ถœ๋ ฅ
10
TGlmZSBpdHNlbGYgaXMgYSBxdW90YXRpb24u
U3VzcGljaW9uIGZvbGxvd3MgY2xvc2Ugb24gbWlzdHJ1c3Qu
#1 Life itself is a quotation.
#2 Suspicion follows close on mistrust.

๋ฌธ์ œ ์ดํ•ด

์˜ˆ์‹œ ๋ฌธ์ž์—ด TGlmZSBpdHNlbGYgaXMgYSBxdW90YXRpb24u ์ธ ๊ฒฝ์šฐ

๋””์ฝ”๋”ฉํ•˜๊ธฐ ์œ„ํ•ด ์ธ์ฝ”๋”ฉ ๊ณผ์ •์„ ๊ฑฐ๊พธ๋กœ ์ง„ํ–‰ํ•œ๋‹ค.

Decoding - STEP 1

Base64 ์ธ์ฝ”๋”ฉ์€ ๊ฐ ๋ฌธ์ž๋ฅผ 6๋น„ํŠธ์”ฉ ๋‚˜๋ˆ„์–ด ์ด์ง„์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ์ด๋ฅผ 10์ง„์ˆ˜๋กœ ๋งคํ•‘ํ•˜์—ฌ ๋ฌธ์ž๋ฅผ ์ธ์ฝ”๋”ฉํ•œ๋‹ค. ๋””์ฝ”๋”ฉ์€ ๊ทธ ๋ฐ˜๋Œ€๋กœ, ์ฃผ์–ด์ง„ ๋ฌธ์ž ํ•˜๋‚˜๊ฐ€ 6๋น„ํŠธ๋กœ ๋ณ€ํ™˜๋œ ๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๋ฏ€๋กœ, ์ด๋ฅผ ๋‹ค์‹œ ์ด์ง„์ˆ˜๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

์˜ˆ์‹œ ๋ฌธ์ž์—ด์—์„œ ๊ฐ ๋ฌธ์ž๋ฅผ 6๋น„ํŠธ๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. :

T -> 19 -> 010011
G -> 6 -> 000110
l -> 37 -> 011011
m -> 38 -> 100110

Z -> 25 -> 011001
S -> 18 -> 010010
B -> 1 -> 000001
p -> 41 -> 101001

Decoding - STEP 2

์ธ์ฝ”๋”ฉ ๊ณผ์ •์—์„œ ํ•œ ๋ฐ”์ดํŠธ์”ฉ 3๊ฐœ์˜ ๋ฌธ์ž๊ฐ€ 24๋น„ํŠธ ๋ฒ„ํผ์— ๋“ค์–ด๊ฐ”๋‹ค. ๊ฐ ๋ฌธ์ž๋Š” 1๋ฐ”์ดํŠธ(8๋น„ํŠธ)์— ํ•ด๋‹นํ•˜๋ฉฐ, 3๊ฐœ์˜ ๋ฌธ์ž๊ฐ€ ๊ฒฐํ•ฉํ•˜์—ฌ 24๋น„ํŠธ๊ฐ€ ๋œ๋‹ค. ๋””์ฝ”๋”ฉ์—์„œ๋Š” ์ด 24๋น„ํŠธ๋ฅผ 8๋น„ํŠธ์”ฉ ๋‚˜๋ˆ„์–ด์„œ ๊ฐ 8๋น„ํŠธ๋ฅผ ๋‹ค์‹œ ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

// 6 bit ์”ฉ ์ด 24bit
(T)010011 (G)000110 (l)011011 (m)100110
// 24bit๋ฅผ 8bit ์”ฉ ๋‚˜๋ˆ”
01001100 01100110 11100110
// ๊ฐ 8bit๋ฅผ ์•„์Šคํ‚ค ํ‘œ๋ฅผ ๋ณด๊ณ  ๋ฌธ์ž๋กœ ๋ณ€ํ™˜
01001100 -> 76 (L)
01101001 -> 105 (i)
01110110 -> 118 (f)	
// 6 bit ์”ฉ ์ด 24bit
(Z)011001 (S)010010 (B)000001 (p)101001
// 24bit๋ฅผ 8bit ์”ฉ ๋‚˜๋ˆ”
01100101 00100000 01101001
// ๊ฐ 8bit๋ฅผ ์•„์Šคํ‚ค ํ‘œ๋ฅผ ๋ณด๊ณ  ๋ฌธ์ž๋กœ ๋ณ€ํ™˜
01100101 -> 101 (e) 
00100000 -> 32 (space)
01101001 -> 105 (i)

๋”ฐ๋ผ์„œ, ์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด ์ค‘ TGlmZSBp ๋Š” Life i ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด TGlmZSBpdHNlbGYgaXMgYSBxdW90YXRpb24u ๋ฅผ ๋ชจ๋‘ ๋””์ฝ”๋”ฉํ•œ ๊ฒฐ๊ณผ๋Š” Life itself is a quotation. ์ด๋‹ค.

code - version 1

package D2;

//SWEA D2 1928๋ฒˆ "Base64 Decoder" ๋ฌธ์ œ ํ’€์ด - java 8์˜ Base64 ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Base64 ๋””์ฝ”๋”ฉ์„ ์ˆ˜ํ–‰

import java.util.*;

public class N1928 {
	
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int T = scanner.nextInt();
		
		StringBuilder result = new StringBuilder();
		
		for (int i = 1; i <= T; i++) {
			String str = scanner.next();
			result.append(String.format("#%d %s\n", i, solution(str)));
		}
		
		System.out.print(result);
		scanner.close();
	}

	public static String solution(String str) {
		
		// Base64 ๋””์ฝ”๋”ฉ ์ˆ˜ํ–‰
        byte[] decodedBytes = Base64.getDecoder().decode(str);
        String decodedString = new String(decodedBytes);
		
		return decodedString;
	}
}

point

Java 8์˜ Base64 ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด Base64 ๋””์ฝ”๋”ฉ์„ ์ˆ˜ํ–‰ํ•จ.

Base64.getDecoder().decode() ๋ฉ”์„œ๋“œ๋Š” ๋‚ด์žฅ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ธฐ๋Šฅ์œผ๋กœ Base64 ๋ฌธ์ž์—ด์„ ๋””์ฝ”๋”ฉํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

  • Base64.getDecoder().decode(str)๋Š” Base64 ํด๋ž˜์Šค์˜ getDecoder() ๋ฉ”์„œ๋“œ๋กœ ๋””์ฝ”๋” ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ๊ทธ ๊ฐ์ฒด์˜ decode() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ Base64๋กœ ์ธ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด์„ ๋””์ฝ”๋”ฉํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

new String(decodedBytes)๋Š” ๋ฐ”์ดํŠธ ๋ฐฐ์—ด์„ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

code - version 2

package D2;

//SWEA D2 1928๋ฒˆ "Base64 Decoder" ๋ฌธ์ œ ํ’€์ด - ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—†์ด ํ•ด๊ฒฐ

import java.util.*;

public class N1928_b {
	
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int T = scanner.nextInt();
		
		StringBuilder result = new StringBuilder();
		
		for (int i = 1; i <= T; i++) {
			String str = scanner.next();
			result.append(String.format("#%d %s\n", i, solution(str)));
		}
		
		System.out.print(result);
		scanner.close();
	}

	public static String solution(String encoded) {
		
		// Base64 ์ธ์ฝ”๋”ฉ์— ์‚ฌ์šฉ๋˜๋Š” ์•ŒํŒŒ๋ฒณ
	    String BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
		
		StringBuilder decoded = new StringBuilder();
		
	    // Base64 ๋ฌธ์ž์—ด์„ 6๋น„ํŠธ ์”ฉ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ ๋ฌธ์ž๋ฅผ ํ•ด๋‹น 6๋น„ํŠธ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ 
	    StringBuilder binaryString = new StringBuilder();
	    
	    for (int i = 0; i < encoded.length(); i++) {
	    	//Base64 ๋ฌธ์ž์—ด ๋‚ด ๊ฐ ๋ฌธ์ž๋ฅผ 6๋น„ํŠธ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜
			int index = BASE64_ALPHABET.indexOf(encoded.charAt(i));
			
			// index ๊ฐ’์„ 6๋น„ํŠธ ์ด์ง„์ˆ˜๋กœ ๋ณ€ํ™˜ํ•ด์„œ ์ด์–ด ๋ถ™์ธ๋‹ค.
			String binaryValue = String.format("%6s", Integer.toBinaryString(index)).replace(' ', '0');
			binaryString.append(binaryValue);
		}
	    
	    // 8๋น„ํŠธ๋กœ ๋‚˜๋ˆˆ ๋’ค, 8๋น„ํŠธ ๊ฐ’์„ ๋ฌธ์ž๋กœ ๋ณ€ํ™˜
	   for (int i = 0; i < binaryString.length(); i += 8) {
		   String byteString = binaryString.substring(i, i + 8);
		   int byteValue = Integer.parseInt(byteString, 2);
		   decoded.append((char) byteValue);
	   }
		
		return decoded.toString();
	}
}

point

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—†์ด ๋ฌธ์ œ ํ•ด๊ฒฐ.

  1. Base64 ๋ฌธ์ž์—ด์„ 6๋น„ํŠธ์”ฉ ๋‚˜๋ˆ„์–ด ์ด์ง„์ˆ˜๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

    Base64_ALPHABET.indexOf() ๋ฅผ ์‚ฌ์šฉํ•ด ํ•ด๋‹น ๋ฌธ์ž๊ฐ€ ๋ฌด์—‡์ธ์ง€๋ฅผ ์ฐพ๋Š”๋‹ค.

    String.format("%6s", Integer.toBinaryString(index)).replace(' ', '0') ๋กœ ๊ทธ ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ์ด์ง„์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ด 6๋น„ํŠธ ์ด์ง„์ˆ˜๋ฅผ ์–ป๋Š”๋‹ค.

    • String.format(โ€%6sโ€, โ€œ101โ€) โ†’ 6์ž๋ฆฌ ๋ฌธ์ž์—ด์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์˜ค๋ฅธ์ชฝ ์ •๋ ฌ, 6์ž๋ฆฌ๋ฅผ ์ฑ„์šฐ๊ธฐ ์œ„ํ•ด ์•ž์˜ 3์ž๋ฆฌ๋ฅผ ๊ณต๋ฐฑ์œผ๋กœ ์ฑ„์›€โ€œ 101"

    • Integer.toBinaryString(index) โ†’ index๋ฅผ ์ด์ง„์ˆ˜๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

    • replace(โ€™ โ€˜, โ€˜0โ€™ ) โ†’ ์•ž์— ๊ณต๋ฐฑ์œผ๋กœ ์ฑ„์šด ๋ถ€๋ถ„์„ 0์œผ๋กœ ๋ฐ”๊พผ๋‹ค. โ€œ 101" โ†’ 000101

  2. ์ด 6๋น„ํŠธ๋“ค์„ 8๋น„ํŠธ์”ฉ ๋‚˜๋ˆ„์–ด 10์ง„์ˆ˜๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

    8๋น„ํŠธ์”ฉ ๋‚˜๋ˆ ์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋ณต๋ฌธ์˜ ์ฆ๊ฐ€๋Ÿ‰์€ i += 8 ์ด๋‹ค.

    String byteString = binaryString.substring(i, i + 8); โ†’ binaryString์˜ i๋ฒˆ์งธ ์œ„์น˜๋ถ€ํ„ฐ i + 8๋ฒˆ์งธ ์œ„์น˜๊นŒ์ง€ 8๋น„ํŠธ ๊ธธ์ด์˜ ๋ถ€๋ถ„ ๋ฌธ์ž์—ด์„ ์ถ”์ถœ

    Integer.parsInt(byteString, 2); โ†’ ์ถ”์ถœํ•œ byteString์„ ์ด์ง„์ˆ˜๋กœ ํ•ด์„ํ•ด ์ •์ˆ˜๋กœ ๋ณ€ํ™˜

    decoded.append((char) byteValue) โ†’ byteValue๋ฅผ char๋กœ ๋ณ€ํ™˜ํ•ด decoded์— ์ถ”๊ฐ€ํ•œ๋‹ค. byteValue๋Š” ASCII ์ฝ”๋“œ ๊ฐ’์ด๋ฏ€๋กœ char๋กœ ๋ณ€ํ™˜ํ•ด ํ•ด๋‹น ASCII ๋ฌธ์ž๋ฅผ ์–ป๋Š”๋‹ค.

  3. ๊ฐ 10์ง„์ˆ˜ ๊ฐ’์„ ASCII ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•ด ์›๋ž˜ ๋ฌธ์ž์—ด์„ ๋ณต์›ํ•œ๋‹ค.

profile
๐ŸŒฑ

0๊ฐœ์˜ ๋Œ“๊ธ€