์ ๋ ฅ์ผ๋ก 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 ์ ํ๋ค.
์ฐ์ 24๋นํธ ๋ฒํผ์ ์์ชฝ(MSB)๋ถํฐ ํ byte์ฉ 3 byte์ ๋ฌธ์๋ฅผ ์ง์ด๋ฃ๋๋ค.
๋ฒํผ์ ์์ชฝ๋ถํฐ 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. ์ด๋ค.
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;
}
}
Java 8์ Base64 ํด๋์ค๋ฅผ ์ฌ์ฉํด Base64 ๋์ฝ๋ฉ์ ์ํํจ.
Base64.getDecoder().decode() ๋ฉ์๋๋ ๋ด์ฅ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ธฐ๋ฅ์ผ๋ก Base64 ๋ฌธ์์ด์ ๋์ฝ๋ฉํ๋๋ฐ ์ฌ์ฉ๋๋ค.
Base64.getDecoder().decode(str)๋ Base64 ํด๋์ค์ getDecoder() ๋ฉ์๋๋ก ๋์ฝ๋ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๊ณ , ๊ทธ ๊ฐ์ฒด์ decode() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ Base64๋ก ์ธ์ฝ๋ฉ๋ ๋ฌธ์์ด์ ๋์ฝ๋ฉํ๋ ์ญํ ์ ํ๋ค.new String(decodedBytes)๋ ๋ฐ์ดํธ ๋ฐฐ์ด์ ๋ฌธ์์ด๋ก ๋ณํํ๋ค.
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();
}
}
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ด ๋ฌธ์ ํด๊ฒฐ.
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
์ด 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 ๋ฌธ์๋ฅผ ์ป๋๋ค.
๊ฐ 10์ง์ ๊ฐ์ ASCII ๋ฌธ์๋ก ๋ณํํด ์๋ ๋ฌธ์์ด์ ๋ณต์ํ๋ค.