문자 집합(Character Set)
컴퓨터는 사람이 일반적으로 사용하는 10진수 숫자를 어떻게 저장할까?
예를 들어 50이라는 숫자를 메모리에 저장한다고 하면 컴퓨터는 2진수로 (110010) 바꿔서 저장을 하게 된다.
왜냐하면 컴퓨터는 0, 1 중 하나만 담을 수 있는 비트라는 최소 단위를 가지고 정보를 처리하기 때문이다.
(메모리는 작은 전자 스위치인 트랜지스터로 이루어져 있는데 전기가 흐르거나, 흐르지 않는 상태로 0, 1 표현)
그렇다면 지금 사용하고 있는 한글, 영어 등의 문자는 어떻게 컴퓨터가 받아들일까?
사람들은 문자나 기호를 컴퓨터에서 사용할 수 있도록 집합을 정의하였는데 이를 문자 집합이라고 한다.
즉 문자의 경우 이 집합에 정의된 내용에 따라 숫자로 변환하고 이를 2진수로 바꾸어서 저장하는 것이다.
- 문자 인코딩 → 문자나 기호를 컴퓨터에 저장, 통신 목적으로 부호화 하는 것
- 문자 디코딩 → 부호화 된 문자를 다시 본래 문자로 표현하는 것
문자 집합의 종류
ASCII 문자 집합 : 초기 컴퓨터에서 주로 알파벳, 숫자, 스페이스, 엔터 등을 표현하기 위해 정의한 표준 문자 집합으로 7비트를 사용해서 128가지의 문자를 표현하였다.
아래는 아스키 코드 표의 일부를 가져왔는데, 문자 A는 숫자 65로 표현된다.
034 | " | 058 | : | 082 | R |
035 | # | 059 | ; | 083 | S |
041 | ) | 065 | A | 089 | Y |
042 | * | 066 | B | 090 | Z |
043 | + | 067 | C | 125 | } |
044 | , | 068 | D | 126 | ~ |
045 | - | 069 | E | 127 | DEL |
ISO_8859_1 : 서유럽 문자를 표현하는 문자 집합으로 기존 ASCII 문자 집합에 서유럽 문자, 특수 문자를 추가하였고 8비트를 사용해서 256가지의 문자를 표현한다. (기존 ASCII 문자 집합과 호환 가능)
EUC-KR : 초창기 등장한 한글 문자 집합으로 자주 사용하는 한글, 한자, 일본어를 포함한 문자 집합이다. 2Byte를 사용하여 총 65536가지의 문자가 표현 가능하다. 역시 기존 ASCII 문자 집합과 호환이 가능하며 영어는 1Byte, 한글은 2Byte를 사용한다.
MS949 : 마이크로소프트가 EUC-KR를 확장하여 만든 것으로 모든 한글의 표현이 가능하다. (기존에는 삙과 같은 음절은 표현 X) 역시 기존 ASCII 문자 집합과 호환 가능, 영어는 1Byte, 한글은 2Byte를 사용하고, 윈도우 시스템에서 주로 사용한다.
유니코드
위 문자 집합들은 특정 언어를 대상으로 만들어졌기 때문에 호환성에 문제가 있다. 따라서 전 세계 문자를 동일하게 표현하기 위한 하나의 표준이 등장하였는데 이것이 유니코드이다.
UTF-8
1. 1~4Byte를 사용해서 문자를 인코딩. → 문자에 따라 바이트 수가 변하는 가변 길이의 인코딩 방식1byte: ASCII 문자
- 2byte: 라틴어 확장 문자
- 3byte: 한글, 한자, 일본어
- 4byte: 이모지 등등
2. ASCII 문자는 1바이트로 표현하며 ASCII 호환이 가능하지만, 한글의 경우 많은 바이트를 사용하여 표현한다.
3. 사실상 현재 표준 인코딩 기술
UTF-16
1. 2Byte, 4Byte를 사용해서 문자를 표현한다.
- 영어, 한국어, 한자, 일본어 등 2Byte로 표현
- 이모지의 경우 4Byte로 표현
- 자바에서 내부적으로 UTF-16 인코딩 방식을 사용. (자바에서 char 타입은 2Byte)
2. 하지만 ASCII 문자와 호환이 되지 않으며, 가장 많이 사용하는 영어의 경우도 ASCII 보다 1Byte를 더 사용해서 표현한다는 단점이 있다.
자바에서 문자 집합
- 조회 방법
// 이용 가능한 모든 문자 집합 (자바 + OS 제공)
SortedMap<String, Charset> charsets = Charset.availableCharsets();
for (String charsetName : charsets.keySet()) {
System.out.println("charsetName = " + charsetName);
}
- 문자 인코딩, 디코딩
Charset utf8 = StandardCharsets.UTF_8;
String text = "가";
byte[] bytes = text.getBytes(utf8);
System.out.println(Arrays.toString(bytes)); // 인코딩
String decodedText = new String(bytes, utf8); //. 디코딩
System.out.println(decodedText);
결과 : [-22, -80, -128] 가