데이터를 컴퓨터에서 처라히가 위한 중요한 과정으로, 문자를 숫자로 변환하거나 숫자를 문자로 변환하는 방식.
문자를 컴퓨터가 이해할 수 있는 숫자로 변경하는 것
String writeString = "ABC";
// 문자 -> byte 변환 UTF-8 인코딩
byte[] writeBytes = writeString.getBytes(UTF_8);
숫자로 변환된 데이터를 다시 원래의 문자로 변환하는 과정
byte[] bytes = fis.readAllBytes();
String readString = new String(bytes, UTF_8);
인코딩/디코딩 예시
문자 -> 숫자 (인코딩): "가"라는 문자를 EUC-KR로 인코딩하면 0xB0A1(16진수)로 표현.
숫자 -> 문자 (디코딩): 0xB0A1을 EUC-KR로 디코딩하면 "가"라는 문자로 변환.
인코딩 방식에 따라 문자가 표현되는 방식이 다르다. 각 인코딩 방식은 사용하는 바이트 수와 지원하는 문자 집합에 따라 다르게 작동한다.
특징: 한국어 완성형 문자를 인코딩하는 표준 방식 중 하나이다.
바이트 수: 한글과 일부 특수 문자를 2바이트로 인코딩한다.
예시: "가" → 0xB0A1
특징: 마이크로소프트에서 EUC-KR을 확장한 인코딩 방식으로, 더 많은 문자 집합을 지원한다.
바이트 수: 한글을 2바이트로 인코딩한다.
예시: "가" → 0xB0A1 (EUC-KR과 동일한 값)
특징: Unicode 문자 집합을 사용하는 인코딩 방식이다.
바이트 수: 대부분의 문자를 2바이트로 인코딩하지만, 일부 문자는 4바이트를 사용하기도 한다.
예시: "가" → 0xAC00
3바이트 인코딩 방식
특징: 유니코드를 가변 길이 인코딩 방식으로 표현하며, 웹에서 가장 널리 사용되는 방식이다.
바이트 수: ASCII 문자는 1바이트, 한글과 같은 비ASCII 문자는 3바이트로 인코딩된다.
예시: "가" → 0xEAB080
package charset;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import static java.nio.charset.StandardCharsets.*;
public class EncodingMain1 {
private static final Charset EUC_KR = Charset.forName("EUC-KR");
private static final Charset MS_949 = Charset.forName("MS949");
public static void main(String[] args) {
System.out.println("ASCII 영문 처리 ");
encoding("A", US_ASCII);
encoding("A", ISO_8859_1);
encoding("A", EUC_KR);
encoding("A", UTF_8);
encoding("A", UTF_16BE); // 2byte 사용 -> 호환 불가
System.out.println("== 한글 지원 ==");
encoding("가", EUC_KR);
encoding("가", MS_949);
encoding("가", UTF_8); // 3byte
encoding("가", UTF_16BE);
String str = "A";
byte[] bytes = str.getBytes(); // 기본값 UTF-8 사용
System.out.println("bytes = " + Arrays.toString(bytes));
}
private static void encoding(String text, Charset charset){
byte[] bytes = text.getBytes(charset);
System.out.printf("%s -> [%s] 인코딩 -> %s %sbyte\n", text, charset, Arrays.toString(bytes), bytes.length);
}
}
package charset;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import static java.nio.charset.StandardCharsets.*;
public class EncodingMain2 {
private static final Charset EUC_KR = Charset.forName("EUC-KR");
private static final Charset MS_949 = Charset.forName("MS949");
public static void main(String[] args) {
System.out.println("== 영문 ASCII 인코딩 ==");
test("A", US_ASCII, US_ASCII);
test("A", US_ASCII, ISO_8859_1); // ASCII 확장(LATIN-1)
test("A", US_ASCII, EUC_KR); // ASCII 포함
test("A", US_ASCII, MS_949); // ASCII 포함
test("A", US_ASCII, UTF_8); // ASCII 포함
test("A", US_ASCII, UTF_16BE); // UTF_16 디코딩 실패
System.out.println("==한글 인코딩 - 기본 == ");
test("가", US_ASCII, US_ASCII); // X
test("가", ISO_8859_1, ISO_8859_1); // X
test("가", EUC_KR, EUC_KR); // O
test("가", MS_949, MS_949); // O
test("가", UTF_8, UTF_8); // O
test("가", UTF_16BE, UTF_16BE); // O
System.out.println("==한글 인코딩 - 복잡한 문자 == ");
test("쀍", EUC_KR, EUC_KR);
test("쀍", MS_949, MS_949);
test("쀍", UTF_8, UTF_8);
test("쀍", UTF_16BE, UTF_16BE);
System.out.println("== 한글 인코딩 - 디코딩이 다른 경우 == ");
test("가", EUC_KR, MS_949);
test("쀍", MS_949, EUC_KR); // 인코딩 가능, 디코딩 X
test("가", EUC_KR, UTF_8); // X
test("가", MS_949, UTF_8); // X
test("가", UTF_8, MS_949); // X
System.out.println("== 영문 인코딩 - 디코딩이 다른 경우 ==");
test("A", EUC_KR, UTF_8);
test("A", MS_949, UTF_8);
test("A", UTF_8, MS_949);
test("A", UTF_16BE, MS_949);
}
private static void test(String text, Charset encodingCharset, Charset decodingCharset) {
byte[] encoded = text.getBytes(encodingCharset);
String decoded = new String(encoded, decodingCharset);
System.out.printf("%s -> [%s] 인코딩 -> %s %sbyte -> [%s] 디코딩 -> %s\n",
text , encodingCharset, Arrays.toString(encoded), encoded.length,
decodingCharset, decoded);
}
}
2byte: EUC-KR, MS949, UTF-16
3byte: UTF-8
한글을 인코딩할 때 UTF-8과 EUC-KR(MS949)는 서로 호환되지 않는다.
ASCII 영문 인코딩: UTF-16을 제외하고 모두 호환
사실상 표준인 UTF-8 사용
한글이 깨지는 가장 큰 2가지 이유