컴퓨터과학 개론 책을 읽다가 유니코드에 대한 부분에서 궁금증이 생겼다.
asac부트캠프(sk플래닛) 시험으로 html/css와 java를 1문제씩 풀게 됐는데
html과 css는 공부를 했지만 java는 개발환경 구축도 되어있지 않은 완전 초짜 상태였다.
자바 강의를 내일배움카드부터 다양하게 찾아보다가 생활코딩과 프로그래머스에서 제공하는 무료 강의가 있어서 저장은 해두었는데, 학습까지 이어지진 않은 상황이었다.
시험 자체에서 웹서핑해서 공부하면서 풀어도 된다고 명시되어서 개발환경구축부터 차례차례 진행하는데
아무래도 강의 자료가 2~3년 정도 전 꺼다 보니 강의 내용과 다른 부분이 꽤 있었다.
deprecated되거나 변화한 부분이 많은 만큼 개발자 세계의 변화속도가 빠르다는 뜻일 것이다.
발생한 오류 중에 인코딩 방식이 지정되지 않아 발생한 것이 있었는데, 디폴트 값으로 utf-8이 되어있는 것 같은데
해제하고 직접 utf-8방식을 골라주니 해결됐었다.
그러고 밤에 책을 읽다가 유니코드 부분에서 궁금한 점이 생긴 것이다.
책에서는 유니코드가 2바이트고 아스키코드와 호환이 되어 표준으로 쓸 때 장점이 있다고 했는데
사실 유니코드는 예전부터 21bit로 확장되어 있었다.
20살때 보던 전공책에도 유니코드는 2바이트라고 했던 것 같은데 참 개정이 안되는 것 같다.
유니코드 자체는 21비트이고 16진법 표현 시 U+00FFFF 이렇게 이루어진다.
U+는 유니코드라는 의미
00부분은 문자 평면을 나타내는데, 평면이라고 해서 거창해보일 수 있으나 문자들을 65536개씩 분류해둔 것을 평면이라 부르는 것일 뿐이다.
00평면부터 10평면까지 17개의 평면이 있으며 00평면에는 2바이트시절에 쓰던, 전 세계에서 주로 쓰이는 문자들이 수록되어 있다. 01평면 02평면 ... 등에는 한자가 저장되거나 하는 식이다.
사실 한글도 자음과 모음 수는 많다고 볼 수 없지만 이를 조합한 모든 문자를 유니코드에 각각 저장해야하기에 생각보다 저장할 양이 많다.
가 나 다 라 이런건 말할 것도 없고 뷁 걁 이런 일본어가 깨질 때 발생하는 글자들도 모두 수록되어있다.
한자는 이보다 더 많은 8만자 가량이라는데, 한자 문화권이 방대하고, 각 문화권마다 한자가 다른 방식으로 발전된 경우가 많아서 그 모든 한자들을 다 저장하려고 여러 평면을 사용하게 됐다.
실제로 00평면이라기 보단 영어로 BMP라고 다국어 기본 평면 이런식으로 이름이 지어져 있다.
한자 외에도 고대에 쓰인 문자나 여러 기호들, 인공언어 (공학에서 쓰이거나 사람이 특수한 목적으로 만든 언어들), 이모지, 음표 등 어지간한 건 다 등록이 되어 있다.
이론상 17 * 65536 개의 문자를 사용할 수 있는데, 아직 절반 이상이 비어있는 상태고, 한 평면에서도 65536개를 모두 채우지 않고 특정 위치에 빈 칸을 둔다.
유니코드에서 매번 회의를 통해 어떤 문자나 기호를 추가할 지 정하고 추가한다고 한다.
이미 왠만한 건 다 수록되어있기에 남은 공간을 다 채우려면 외계인과 만나 새로운 언어를 접하거나, 아틀란티스 유적이라도 발견되어야하지 않을까? 혹은 미래의 인공지능이 독자적인 언어를 만든다거나
인코딩방식인 utf는 유니코드 트랜스폼 포맷이었나? 암튼 말그대로 유니코드를 인코딩하는 방식인데
21비트의 정보를 어떻게 컴퓨터에게 이해시키냐는 의미이다.
21비트를 그냥 줘버리면 어디가 시작이고 어디가 끝인지도 모르니 해석이 불가능할테니
일정한 양식을 정해서 21비트의 정보를 전해주는 것이다.
utf는 8 16 32가 있는데, 간단히 설명해보겠다.
32방식은 유니코드 1개를 32비트 단위로 인코딩한다. 따라서 특별한 양식없이 앞자리는 0으로 모두 채우고 21비트를 그대로 채우면 된다. 32비트중 11비트를 0으로 채워야하니 공간 낭비가 심해 저장용으로는 적합하지 않다. 예전에는 매번 11비트의 0을 읽어야하니 속도면에서도 장점이 없었는데, 기술이 발전하면서 컴퓨터가 기본 32비트 단위로 동작하기에 속도면에서 장점이 생겼다. 그래서 주로 프로그램 내부에서 사용한다고 한다.
16방식은 16비트 단위로 인코딩하는데, 유니코드가 2바이트인 시절엔 문제가 없었겠지만, 00평면을 넘어가면 16비트만으로 표현이 불가능하기에 16비트씩 2개로 나누어 표현한다. 16비트 2개가 연결된다는 의미로 각 16비트 앞비트를 특정 패턴으로 채우고 표현할 유니코드를 공식에 맞춰 넣는다. 유니코드 이전에 쓰던 ucs-2라는 방식과 호환되는 장점이 있으나 리틀엔디안이냐 빅엔디안이냐에 따라 인코딩과 디코딩방식이 달라지고 이는 에러발생 여지를 남긴다.
마이크로소프트는 유니코드를 매우 빨리 도입했는데, 도입당시에는 ucs-2와의 호환을 위해 utf-16방식을 택했다. 지금 대세는 utf-8로 굳혀진 상태이나 너무 많은 레거시 코드들이 utf-16방식이라 호환을 위해 유저가 사용하는 부분을 제외하면 대부분이 utf-16방식으로 이루어져 있다. 너무 빨리 도입한 나머지 생긴 부작용이라고 할 수 있겠다.
8방식은 유니코드를 길이에 따라 1바이트에서 4바이트로 가변적으로 표현한다.
7비트이하일 경우 1바이트로 제일 앞자리를 0으로해서 7비트를 채우고
그 이상일 경우 필요한 바이트 수에 따라서 표현법이 살짝 다르다.
2바이트가 필요한 경우 첫바이트는 110으로 시작하고
3바이트가 필요하면 1110, 4바이트가 필요하면 11110이 되는 식이다.
그리고 뒤에 따라오는 바이트들은 앞자리에 모두 10으로 시작하게 된다.
즉 첫 바이트는 몇개의 바이트로 이루어진 유니코드인지 알려주는 비트로 시작하고
나머지 바이트들은 일행이라는 뜻으로 10이라는 비트로 시작하는 것이다.
표현할 유니코드는 저 비트들을 제외한 곳에 뒤에서부터 차례대로 입력한다.
유니코드 길이에 따라 가변적으로 조절할 수 있어 무조건 2바이트로 사용했을 때보다 저장 용량이 적어질 가능성이 높은 장점이 있다. 0001을 01로만 보낼 수 있으니 말이다.
대신 한글처럼 대부분이 2바이트를 사용하는 유니코드는 형식상 3바이트가 되어버리는 단점도 생긴다.
영어나 숫자 표현시에는 용량이 줄지만, 한글은 늘어나는 현상.
다만 완전히 한글로 쓰여진 문서가 아닌 html 같은 문서들은 영어나 숫자가 많아 오히려 용량이 줄어들 수도 있다.(16방식에서 8방식으로 바꾸면)
가장 큰 장점은 아스키코드와 호환이 된다는 건데, 7비트까지는 아스키코드와 같은 방식으로 1바이트단위로 인코딩하기 때문이고, 이 호환성은 아스키코드로 작성된 문서들을 볼 때 큰 장점이 된다.
어지간한 경우면 utf-8을 디폴트로 사용하면 되겠다.
아주 특수한 경우가 생길 시 상기한 특징들을 바탕으로 다른 방식을 선택하면 된다.
'컴퓨터과학' 카테고리의 다른 글
2의 보수부터 부동소수점을 지나 비교연산까지 (1) | 2024.10.14 |
---|