2015년 6월 26일 금요일

유니코드 인코딩이 이렇게 복잡하게 된 사연 (9)




유니코드 인코딩의 종류는 UTF-1, UTF-5, UTF-6, UTF-7, UTF-8, UTF-9, UTF-16, UTF-18, UTF-32, UTF-EBCDIC, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE와 같이 다양하다. 지금은 사장된 것들도 있지만 초급 개발자에게는 여간 헷갈리는 것이 아니다. 

애초에 ASCII가 아니고 유니코드를 사용했다면, 특히 4바이트 유니코드를 사용했다면 지금과 같이 수많은 유니코드 인코딩 때문에 헷갈거나 변환을 해야 하는 번거로움은 없었을 것이다. 현재와 고대 문자만 표현한다면 3바이트로도 충분하지만 4바이트가 컴퓨터 연산에 편리하고 먼 미래에 어떻게 될지 모르기 때문에 4바이트가 안전할 것이다.  하지만 뒤늦게 나온 유니코드는 ASCII와 호환성 등 여러 가지 이유로 인해서 수많은 인코딩이 존재한다. 

인류가 유일한 표준 문자세트로 4바이트 유니코드를 사용하고 있다면 영어 문서를 저장하기 위해서 지금의 4배 용량의 저장장치가 필요하다. 지금은 별일 아니지만 과거에는 저장 용량은 매우 큰 이슈였다. 필자가 대학생 때 샀던 PC에는 40만원 주고 산 40MB짜리 그 당시로는 대용량 HDD가 달려 있었다. 지금은 2바이트, 4바이트 유니코드가 있지만 여전히 저장 용량 절약 이슈가 존재한다. 언제가 될지 기약할 수 없지만 모든 시스템과 파일이 4바이트 유니코드 단일 체계를 사용하는 날이 올 것이다. 몇십년 후일지 몇백년 후일지는 모르겠다.
(유니코드 인코딩과 타 인코딩 간의 관계)

그럼 유니코드 관련 주요 인코딩의 특징 및 관계, 사연에 대해서 알아보자. 지금은 거의 쓰지 않는 인코딩은 알 필요가 없다.

1. MBCS (Multi Byte Character Set)

유니코드 인코딩이 아니며 ASCII에서 표현하지 못하는 각국의 문자를 표현하기 위해서 사용하는 수많은 문자세트와 인코딩이다. 보통 1,2바이트를 사용하며 ASCII를 포함한다. 나라별로 로케일별로 제각각 이어서 서로 호환이 안 된다. 아직도 수많은 Application이 유니코드 기반이 아니고 MBCS 기반이며 소프트웨어 국제화의 발목을 잡고 있다. Application이 MBCS 기반이어도 Windows는 내부적으로 유니코드(UCS-2)를 쓰기 때문에 Application과 OS를 오가며 문자열들은 계속 변환이 일어나고 이런 과정에서 예상치 못하게 깨지는 문자들이 나오게 된다. 최근의 새로운 개발 환경이나 플랫폼들은 아예 MBCS를 지원하지 않고 유니코드 Application만 제작할 수 있는 경우도 많다. 이런 환경에서만 개발하는 개발자는 MBCS가 뭔지도 모르고 자연스럽게 유니코드 Application을 만들 것이다.

2. UCS-2 (Unicode Character Set-2)

유니코드 문자세트이며 인코딩이다. Windows는 내부에서 UCS-2를 사용한다. C언어에서는 wchar_t(유니코드문자 자료형)로 표현한다. Unix나 Linux에서는 wchar_t는 UCS-4이다. Unix나 Linux에서는 한 글자에 4바이트이니 주의를 하자. 모든 문자가 깔끔하게 2바이트라서 연산이 매우 빠르다. 100바이트에는 딱 50글자가 들어간다. 하지만 ASCII 문자를 표현하기 위해서 NULL문자가 포함되어 있어서 기존의 char * 자료형에는 담을 수가 없다. 또한 문자열 관련된 수많은 함수를 다시 만들어야 했다. 파일에 그대로 기록할 경우 NULL문자로 인해서 기존의 Application이 텍스트 파일이 아닌 바이너리 파일로 인식하는 문제가 있다. 주로 Application 내부 데이터 용도로 사용한다고 보면 된다.

3. UTF-8 (Unicode Transformation Format-8)

유니코드 중에서 가장 널리 쓰이는 인코딩이다. 1~6바이트를 사용한다. BMP만 표현한다면 4바이트까지만 사용하면 된다. 특히 파일저장, 데이터 전송 등에 많이 사용한다. UTF-8의 가장 큰 장점은 위 그림에서도 보이듯이 ASCII, ISO8859-1과 호환된다는 것이다. 즉, UTF-8 문서를 처리하는 소프트웨어는 ASCII와 ISO-8859 문서를 변환 없이 그대로 처리할 수 있다. 반대로 UTF-8 인코딩으로 저장한 문서가 과거 미국이나 독일 Application에서 읽힌다. 물론 지원하지 않는 문자는 깨져서 보일 것이지만 열리기는 할 것이다. 미국과 유럽, 특히 영어권에 매우 유리한 인코딩이다. 이는 UTF-8이 가장 널리 쓰이는 이유이기도 하다.

영어로 된 문서를 저장할 때 용량이 매우 작다. 하지만 한국어(한글)는 한 글자당 3바이트로 용량이 낭비된다. 이또한 UTF-8이 인기있는 이유중 하나다.



그 외에도 UTF-8은 여러 장점이 있다. 데이터를 중간부터 보더라도 몇 바이트만 보면 UTF-8 인코딩인지 알 수 있고 데이터 손실도 거의 없다. UTF-8 데이터 구조는 처음부터 이런 장점을 가지도록 설계가 되어 있는데 이를 설계한 사람의 천재성을 엿볼 수 있다.

또 하나의 장점은 문자열 중간에 NULL(0x00)문자가 나오지 않는다는 것이다. 따라서 파일에 저장해도 바이너리 파일로 인식하는 오류가 없고, C언어와 같이 Null terminated string의 자료형에 담을 수가 있다. 이는 하위호환성에서는 큰 장점이 된다.

단점으로는 가변 바이트를 사용하여 글자 개수를 세려면 한 글자씩 개수를 세야 하는 등의 연산 오버헤드가 있다.

4. UTF-16 (Unicode Transformation Format-16)

유니코드 컨소시엄에서 제안한 인코딩이다. UCS-2와 거의 동일하기 때문에 혼동해서 사용하는 경우가 많다. 하지만 UTF-16은 가변 길이이기 때문에 2바이트 고정 길이를 지칭한 경우라면 UCS-2를 말하는 것을 UTF-16이라고 잘못 부르는 것이다. 최초의 UTF-16은 UCS-2와 동일 했기 때문에 그 잔재가 아직도 남아 있는 것 같다.
Java에서는 문자열의 인코딩에 기본적으로 UTF-16(BE)를 사용한다. Java로 개발을 할 때도 문자 인코딩을 제대로 이해하고 있어야 깨지지 않고 제대로 처리를 할 수 있다.

5. UTF-32 (Unicode Transformation Format-32)

4바이트로 고정된 UCS-4와 동일한 인코딩이다. (현재까지는) 모든 문자들이 UTF-32로 통일된다면 인코딩 변환이 필요 없는 세상이 올 것이다. 하지만 저장 공간 낭비가 심해서 인류가 저장 용량에서 완전히 해방되는 날이 되기 전까지는 유일한 표준이 되기는 어려울 것이다. 또한 UTF-8과는 다르게 데이터를 중간부터 보면 어디가 글자의 시작인지 알 수가 없는 단점이 있다.

이 외에도 수많은 유니코드 인코딩이 생겨났지만 거의 사장되다시피 했다.

Byte Order와 BOM 이슈는 나중에 다루도록 하겠다. 

국제화를 이해하기 위한 기초를 다루다 보니 여러 회가 지났는데 다음부터는 본격적인 내용과 기초를 교대로 다뤄볼까 한다.

이 글은 네이버 포스트에 게재할 입니다.

2015년 6월 23일 화요일

한국어(한글) 코드 이야기 (8)


유니코드에 대해서 좀더 알아보기 전에 한국어 코드(문자세트)와 인코딩에 대해서 좀더 알아보자. 

1991년에 유니코드가 탄생한 후에 유니코드는 점점 많은 개발자들이 사용하기 시작해서 영역을 넓혀가고 있다. 물론 언젠가는 유니코드로 통일되는 시기가 올 수도 있겠지만 아직까지는 한국어만 해도 여러 문자세트와 인코딩이 공존을 하고 있고 소프트웨어 개발자에게는 여간 귀찮은 일이 아닐 수 없다. 이에 대해서 잘 알고 있고 경험이 많은 개발자라면 별 문제가 없지만 한국어 문자세트와 인코딩에 대해서 조금 헷갈리는 경우라면 소프트웨어를 개발하면서 수많은 지뢰를 만나게 된다. 그나마 한국어는 중국이나 일본에 비해서는 문자세트와 인코딩의 표준화가 잘되어 있어서 훨씬 수월한 편이라고 할 수 있다.

이제 유니코드가 대세라고 Application을 유니코드를 지원하도록 만든다고 다 해결되는 것은 아니다. 네트워크를 통해서 다른 시스템과 통신을 할 때 다른 인코딩을 사용할 수도 있고, 파일로 저장할 때 다른 형식을 써야 할 때도 많다. 왜냐하면 아직도 수많은 시스템이 유니코드를 지원하지 않고 있고, 우리는 그런 시스템과도 연동을 해야 하기 때문이다.

데이터베이스의 인코딩을 어떤 것을 선택할지도 큰 이슈다. 지금은 누구나 유니코드의 인코딩을 선택하지만 몇 년 전까지만 해도 EUC-KR이나 다른 인코딩을 선택하기도 했다. 이런 경우 시스템의 국제화를 추진하게 되면 심각한 문제에 봉착하게 된다. 데이터베이스 이슈는 추후 별도로 다루도록 하겠다.

우리는 Application을 개발하면서 외부 라이브러리를 사용하기도 한다. 그런데 외부 라이브러리가 유니코드 기반이 아닌 경우도 많다. 그럴 때는 라이브러리를 사용하기 위해서 문자열을 변환해야 하는 복잡한 문제에 봉착하기도 한다. 상황에 따라 다르지만 유니코드와 여러 가지 인코딩이 공존하는 세상에서 개발해야 하는 개발자들은 이런 문제를 겪기도 하고 해결해야 한다는 것을 알아야 한다.

그래서 현재 한국어를 표현하기 위해서 사용되고 있는 문자세트와 인코딩에 대해서 간단하게 집고 가려고 한다. 물론 문자가 깨지는 경우에 이를 해결하는 데는 경험이 훨씬 중요하다. 하지만 문자세트와 인코딩의 지식은 기본으로 필요하다.
(한국어 문자세트와 인코딩 포함 관계)


1. KSC 5601 (문자세트)

한국산업규격 한국어문자집합이다. 공식 명칭은 KS X 1001이다. 1974년 처음 제정되었고 2004년에 마지막 개정이 있었다. 2바이트 부호체계이며 8,836문자를 규정하고 있다. 한글, 숫자, 특수문자, 한자, 로마자, 그리스문자, 키릴문자 등으로 구성되어 있다. 
한글 2,350자와 한자 4,888자를 정의하고 있는데 실제 사용하는 한글과 한자에 비해서는 턱없이 부족한 문제가 있다.

2. EUC-KR (인코딩)

문자세트는 실제 컴퓨터에서 사용하는 코드는 아니다. 컴퓨터에서는 인코딩을 사용하며 EUC-KR은 널리 사용되는 한국어 인코딩 중 하나다. KSC 5601을 그대로 포함하고 있으며 영어 영역은 ASCII를 사용한다. 정확하게는 KS X 1003인데 ASCII라고 알고 있어도 무방하다. EUC-KR은 KSC 5601이 가지고 있는 문제를 그대로 가지고 있다.

3. ISO-2022-KR (인코딩)

지금은 쓸 이유도 없는 인코딩이지만 하위 호환 때문에 가끔 만나게 된다. ISO2022는 원래 둘 이상의 문자집합을 한꺼번에 표현하기 위한 국제 규약이었는데 여기에 한국어를 추가했다. 지금은 상상이 잘 안되지만 과거에는 Email을 전송할 때 7bit로만 전송하던 시절이 있었다. ISO-2022-KR은 8bit를 사용하는 KSC 5601 문자를 7bit로 전환해서 Email를 전송할 수 있게 하였다. 그럼으로써 ISO-2022-KR을 지원하는 Email 클라이언트에서 한국어 Email을 볼 수 있게 되었다. 코드 중간에 0x0e 문자를 만나면 이제부터 한국어라는 뜻이고 0x0f를 만나면 영어로 간주를 한다. 


지금은 Email을 8bit로 전송할 수도 있고, Base64로 인코딩해서 보내는 방법도 있어서 ISO-2022-KR은 쓸 이유가 점점 없어지고 있다. 또한, Email을 아예 유니코드(UTF-8)로 보내는 비율이 점점 늘고 있다. 유니코드로 Email을 보낸다는 의미는 내가 보낸 Email이 전세계 어디서나 문제없이 볼 수 있다는 의미다. 물론 Email 클라이언트가 유니코드를 지원해야 하며 유니코드 폰트가 존재해야 한다. 아직은 모든 시스템이 유니코드의 모든 문자의 폰트를 포함하고 있지 못하다. 이 이슈는 추후 폰트 관련 글에서 따로 다루겠다.

4. CP949 (인코딩)

마이크로소프트에서 사용하는 한국어 코드페이지다. 원래는 KSC5601을 표현하는 코드페이지였으나 KSC5601에 없는 한글 문자가 많아서 8822자의 현대한글을 추가하였다. 이렇게 문자를 새로 추가하다 보니 한국어 코드의 순서가 가나다 순서와는 다르게 뒤죽박죽이 되는 문제가 있다. 하지만 EUC-KR에서는 표현할 수 없는 많은 문자를 표현 할 수 있다. Windows에서 파일로 “똠방각하”를 저장할 때 ANSI 형식 선택해도 KSC5601에 없는 “똠”라를 저장할 수 있는 이유는 Windows는 EUC-KR 대신 CP949를 선택하기 때문이다. 따라서 CP949의 모든 문자를 EUC-KR 인코딩으로 변환할 수는 없다. 이런 변환 과정을 거치면 몇몇 글자는 깨질 수가 있다. OS에 따라서 한국어 문자가 깨지는 상황이 발생했을 때 OS가 어떠한 인코딩을 사용하는지 살펴볼 필요가 있다.



지금은 위 4가지가 아니라면 거의 유니코드일 것이다. 유니코드에 대해서는 추후 자세히 다룰 것이다.

2015년 6월 16일 화요일

유니코드 영토 전쟁의 승리자는? (7)



이번에는 유니코드의 코드 체계에 대해서 간단하게 알아보고자 한다. 소프트웨어 국제화를 필요로 하는 개발자라면 자주는 아니지만 유니코드 내부 코드 체계를 알아야 할 때가 있다. 다양한 플랫폼에서 개발을 할 때 폰트 등과 관련하여 문자가 깨지는 등 복잡한 문제에 봉착할 수 있다. 이때 유니코드의 체계의 원리를 아는 것은 문제를 해결하는데 도움이 될 것이다.

지구상의 문자를 모두 하나의 문자 코드에 집어 넣는 유니코드를 만드는 작업은 쉬울 수가 없었다. 고서적에 쓰는 문자들도 코드화를 해야 하기 때문에 유사이래 탄생한 모든 문자를 포함해야 했다. 그 중에서 압권은 중국어 즉, 한자다. 현재까지 알려진 한자만 10만자가 넘는다는 설이 있고 공식 한자만 8만자가 넘는다. 그러니 2바이트 유니코드 65,536 글자에는 중국의 한자도 다 들어 갈 수 없었다. 

두번째로 문자가 많은 나라는 한국이다. 현대 한국어 글자는 조합 가능한 문자가 1만자가 넘고 한자도 1만5천자는 사용을 한다. 물론 KSC5601에서는 한글 2350자, 한자 4888자를 정의하고 있지만 모든 글자를 표현하기에는 턱없이 모자란 숫자다. 게다가 고어까지 모두 포함하면 조합 가능한 글자는 백만자가 넘는다고 한다. 물론 실제 사용하는 글자는 훨씬 적다.

이런 상황이라면 유니코드 65,536 글자 안에 어느 나라 글자가 많이 포함되느냐가 관건이 될 수 있다. 

1991년 유니코드 1.0에서는 한국어는 완성형코드가 포함되어 있었고 표현 못하는 글자가 수두룩하고 배열도 엉망이었다. 하지만 1996년에개정된 유니코드 2.0에는 한글 조합형의 모든 글자와 옛한글을 표현할 수 있는 코드 11,172개와 한글 자모가 포함되었다. 그 과정에서 유니코드 1.0에 포함된 한글코드는 사장시키고 새로운 코드영역으로 이동을 했는데 이런 대규모 이동은 유니코드 역사상 획기적인 일이었다. 유니코드 2.0부터는 한국어 표기 문제가 거의 해결되었다고 볼 수 있다. 그로인해 유니코드 1.0을 지원하는 소프트웨어가 유니코드2.0과 호환이 안되서 초기에는 불평이 많았지만 이제는 옛날 얘기가 되었다.


한자는 한국, 중국, 대만, 일본, 베트남 등에서 공통으로 많이 쓰는 한자를 통합하여 약 2만7천자를 할당하였다. 그 외의 한자는 다른 Plane에 포함되었다. BMP에 포함된 2만7천자의 한자는 2바이트로 표현이 가능하지만 나머지 한자는 4바이트를 사용해야 표현할 수 있다. 중국의 고서적을 표현할 때는 4바이트 코드를 써야 하며 한국의 옛한글도 코드는 있지만 전용 소프트웨어가 필요하다.

유니코드의 역사는 훨씬 더 복잡하지만 이 정도로 간단히 알아보고 유니코드 안에는 어떠한 글자들이 있는지 구경이나 한번 해보자. 대표적인 코드 영역을 몇가지 소개한다. 굳이 암기할 필요도 없고 미래에 문자가 깨지는 상황이 발생할 때 약간의 도움이 될 때가 있을 것이다.

문자들은 환경에 따라서 폰트의 지원여부 때문에 깨져 보일 수가 있으니 이미지로 표시를 했다.
 

다음 시간에는 한국어의 코드체계와 유니코드 인코딩에 대해서 알아보도록 하겠다.

2015년 6월 9일 화요일

유니코드는 어떻게 탄생했을까? (6)


소프트웨어 국제화를 이해하기 위해서는 유니코드에 대해서 필수적으로 잘 알아야 한다. 유니코드란 말을 들어보지 않은 개발자는 없지만 관련 용어가 매우 많아서 종종 헷갈린다.  게다가 유니코드가 탄생한지 20년도 더 넘었지만 아직도 세상은 유니코드로 통일이 되지 못하고 수많은 문자세트가 넘쳐나고 소프트웨어를 개발하다보면 수시로 문자가 깨지고 문제가 발생한다. 그래서 유니코드를 비롯해서 문자세트와 인코딩에 대해서 간단하게 알아볼 기회를 가지려고 한다. 

먼저, 유니코드는 언제, 왜 탄생했는지 그 역사를 간략하게 알아보자. 필자는 유니코드 탄생 이전부터 개발을 했기 때문에 그 역사를 보아 왔다고 할 수 있다. 유니코드의 역사를 알아보기 위해서 그 이전의 문자세트, 문자인코딩의 역사를 거슬러 올라가보자. 

유니코드를 설명하려면 문자세트 문자인코딩이라는 용어를 구분해야 한다. 흔히 헷갈려 하는 용어다. 문자세트는 그야말로 문자들의 집합이다. 문자들의 집합에 각 문자에 번호를 부여한 것이다. 문자인코딩은 그런 문자들을 어떻게 코드를 할당하느냐를 나타낸 것이다. 문자세트를 특별한 변화 없이 그대로 1:1로 나타내는 문자인코딩도 있고, 별도의 규칙에 의해 변경해서 표기하는 문자인코딩도 있다. KSC5601은 문자세트고 이를 영문자와 합쳐서 그대로 인코딩 한것은 EUC-KR이다. 앞으로 문자세트와 인코딩을 마구 섞어서 사용할 것인데 혼동하지는 말자.

1950년대 최초로 컴퓨터가 탄생하고 초창기 컴퓨터에는 표준 문자세트이라는 것이 없었다. 즉, 컴퓨터마다 다른 문자세트를 사용하고 있었다. 그래서 1967년 미국에서 표준 문자세트를 제정한 것이 ASCII다. 미국에서 만들었기 때문에 알파벳과 숫자 등의 글자로 이루어졌다.

ASCII는 7비트 128글자를 사용하며 거의 모든 문자세트의 기본이 된다. 하지만 ASCII는 유럽글자를 표현 할 수 없었다. 그래서 유럽 사람들은 1980년대 중반 ASCII를 확장하여 ISO-8859를 만들게 된다. ISO-8859의 특징은 기존 ASCII 영역을 건들지 않고 8비트 128글자 영역을 사용하여 미국에서 작성한 문서도 그대로 볼 수 있게 하였다.

ISO-8859-1은 네델란드어, 노르웨이어, 독일어 등 주로 서유럽의 언어를 지원한다.
ISO-8859-2은 체코어, 폴란드어, 헝가리어 등 주로 중앙유럽의 언어를 지원한다.
ISO-8859-3은 터키어 등 주로 남유럽의 언어를 지원한다. 이런 식으로 ISO-8859-16까지 추가되었는데 암기할 필요는 없다. ISO-8859를 사용해도 여러 유럽어를 동시에 표현할 수는 없었다.

그 무렵 아시아에서는 문자세트 혼란의 시기가 도래하였다.

한국에서는 1980년대 초부터 여러 가지 한글 조합형 인코딩을 사용했다. 1987년 KSC5601(KSX1001)이라는 한글(한국어) 완성형 문자세트가 제정된 후 조합형과 완성형은 공존을 하다 조합형은 사라지게 된다. 조합형과 완성형의 팽팽한 균형이 무너진 시점은 윈도우95가 나오면서부터다. 그럼에도 불구하고 그 당시 똠방박하의 "똠"자를 윈도우에서 쓸 수 없다는 것은 많은 이슈가 되었다.


중국과 일본도 제 각각의 문자세트와 인코딩을 정의해서 전세계, 특히 아시아는 문자세트 춘추 전국시대가 되었다. 한나라 안에서도 수많은 문자세트와 인코딩이 넘쳐나고 있었다. 이는 전세계 컴퓨터, 소프트웨어가 서로 호환되지 않는다는 의미를 얘기한다. 알파벳과 숫자를 제외하고는 깨져버리기 일쑤였다.

하나의 인코딩으로 영어와 한국어는 표시할 수 있고, 영어와 일본어도 표현을 할 수 있다. 하지만 영어, 한국어, 일본어, 중국어 이렇게 다양한 언어를 한꺼번에 표현할 수는 없었다. 그래서 탄생한 것이 ISO2022다. 중간에 특수한 문자를 만나면 문자세트가 바뀌는 것이다. ISO2022 인코딩의 문자열은 중간부터 읽을 경우 무슨 문자인지 알 수 없는 약점이 있었다.

80, 90년대 이런 춘추전국 시대에 개발을 해본 개발자라면 이런 혼란을 잘 알고 있을 것이다. 근래에 개발을 시작한 개발자들에게는 먼 옛날 얘기일 것이다.

그 당시에는 대부분의 소프트웨어가 나라별 버전을 따로 만들곤 했다.

이러한 혼동 속에서 하나의 문자세트로 전세계 문자를 모두 표현하려는 움직임이 있었고, 썬마이크로시스템즈, 애플, MS, IBM, 볼랜드 등의 회사들이 유니코드컨소시엄을 만들어서 전세계 문자를 통합한 유니코드(Unicode)를 만들기 시작했다. 참여한 회사들을 보면 거의 미국 회사인 것을 알 수 있다. 미국 회사들이 전세계에 소프트웨어를 팔다보니 본인들이 힘들어서 통합의 필요성을 느낀 것이다. 그렇게 미국이 주도하여 1991년 유니코드 1.0이 탄생한다. 

(유니코드에 포함된 나라별로 다른 문자들)

이렇게 제정된 유니코드의 문자세트는 UCS-2(Universal Character Set 2)라고 불린다. UCS-2를 가지고는 고어를 포함한 전세계 모든 문자를 표현하는데는 한계가 있다. 사실 중국어만 해도 10만 글자가 넘는다. 그래서 UCS-4에는 고대 언어를 포함한 모든 언어가 포함된다. 하지만 우리는 대부분 UCS-2를 사용하며 유니코드라고 말하면 UCS-2를 의미하는 경우가 많다. 단, Unix계열의 OS에서는 4바이트 문자세트인 UCS-4를 기본으로 사용한다.


향후 소개될 소프트웨어 국제화의 내용을 쉽게 이해하기 위해서는 문자세트, 인코딩 그리고 유니코드에 대해서 잘 알아야 한다. 그래서 본 글에서 간략히 소개를 했다. 다음에는 유니코드의 내부를 좀 살펴보고 인코딩 등 유니코드에 대해서 조금 더 알아보자.

이글은 네이버포스트에 게재한 글입니다.

2015년 6월 8일 월요일

직원을 잠재적인 도둑 취급하는 회사


필자는 몇 년 전 A그룹에 강연을 하러 갔다가 곤란한 일을 겪은 적이 있다. 한국 대부분의 대기업이 그렇듯이 보안이 매우 엄격한 회사였다. 나는 직원들의 안내대로 메모리, 외장하드를 모두 빼놓고 회사로 들어갔다. 하지만 강연이 끝나고 나오는 과정에서 X-Ray 검색대에서 와이브로 단말기가 발견이 된 것이다. 보안 담당자는 와이브로 단말기는 압수하고 조사 후 일주일 정도나 뒤에 돌려준다는 것이다.
필자는 이동이 잦고 와이브로를 통해서 인터넷을 사용했기 때문에 이런 처사는 받아들일 수 없었다. 그리고 반입금지 물품 안내에 와이브로는 있지도 않았었다. 결국 임원분이 보증을 서서 해결을 했는데 어이 없는 해프닝이 아닐 수 없었다.
강연을 하러 간 강사를 잠재적인 도둑 취급하는 것은 너무한 처사가 아닐까 생각도 들었지만 먼저 직원들은 얼마나 불편할까 하는 측은함도 들었다. 하지만 몇몇 직원들은 이러한 공항 보안 검색대보다 철저한 보안 절차에 익숙해져서 당연하게 생각하고 있었다.
사실 회사 입구에 있는 보안 검색대는 직원들을 잠재적인 도둑 취급하는 것 같아서 기분은 별로지만 잠깐의 불편함만 감수하면 그럭저럭 견딜만하다. 정작 과도한 보안 정책의 문제는 실제 일을 할 때 발생한다. 회사마다 보안정책이 다르지만 보안이 철저할수록 개발자들은 일하기 힘들어진다.
개발자를 소스코드를 훔쳐갈 수 있는 잠재적인 도둑으로 보고 소스코드 접근을 철저히 통제하는 회사가 많다. 자신이 고칠 소스코드만 승인을 거쳐서 내려 받을 수 있도록 하거나 전체 소스코드는 절대로 보지 못하도록 하기도 한다. USB는 아예 차단을 하거나 소스코드를 눈으로 볼 수는 있지만 파일은 접근하지 못하도록 하기도 한다. 소스코드를 사진으로 찍어 갈 수 있다고 휴대전화 카메라에 스티커를 붙이기도 한다.
물론 보안은 매우 중요하다. 하지만 우리 주변에서 벌어지고 있는 소프트웨어 회사들의 보안 정책을 보면 소프트웨어를 이해하지 못한 경영진들이 소프트웨어를 잘 개발하지 못하게 방해하고 있다는 생각이 든다.
반도체 공장에서 설계도면 훔쳐가면 큰 일이 나듯이 소프트웨어도 소스코드를 훔쳐가면 큰 일 나는 것으로 생각한다. 그럼 A사의 개발자들에게 물어보자. 이렇게 보안을 철저하게 하면 개발자가 절대로 소스코드를 가지고 집에 갈 수 없나요? 대답은 당연히 아무리 보안을 철저히 해도 개발자는 모든 소스코드를 들고 집으로 갈 수 있다. 그리고 개발자는 집에서 일을 하기도 한다.
이것을 보고 있으면 우리나라 인터넷 뱅킹이 생각난다. 보안을 철저히 한다고 액티브X에 키보드보안, 개인방화벽, 보안카드, 인증서, OTP 등 수많은 장치들을 두어서 인터넷 뱅킹을 불편하게 하고 있지만 사고는 계속 발생한다. 그럴수록 점점 더 복잡하게 만든다. 그렇다고 보안사고가 잘 줄지 않고 있다. 복잡할수록 구멍이 많아진다.
소프트웨어 회사에서도 개발자가 소스코드를 훔쳐가려면 다 훔쳐갈 수 있다. 보안 담당자들은 개발자들과 창과 방패의 싸움을 해서는 보안도 못 지키고 개발 효율만 엄청 떨어질 뿐이다. 경영자는 보안 담당자의 목소리만 들어서는 안된다. 개발자들의 목소리도 균형 있게 들어야 한다. 보안도 지키면서 개발 효율도 떨어뜨리지 않는 방법을 치열하게 연구해야 한다.
하지만 대부분의 회사는 보안 담당자(전문가는 아닌)의 목소리가 크고 개발자들의 불편하다는 아우성은 귀담아 듣지도 않는다. 보안을 위해서는 어쩔 수 없다고 생각한다. 생산성을 중요시하는 경영진들이 이런 비효율적인 결정을 하는 이유는 직원들을 잠재적인 도둑, 또는 노예 취급을 하기 때문으로 생각한다. 그렇다고 보안이 잘되는 것도 아니다.
보안을 강조하는 회사에서는 소스코드를 신주단지 모시도록 하지만 소프트웨어 회사에서 소스코드의 보안적인 가치는 별로 없다. 사실 자사에서도 자신들이 개발한 소프트웨어의 소스코드를 유지보수하기가 쉽지 않다. 그런데 이런 소스코드가 유출이 된들 누가 이 소스코드를 가지고 소프트웨어를 흉내 내서 만들어 낼 수 있을까? 중요한 것은 개발자들의 경험과 노하우다. 소스코드보다 개발자를 지키는 것이 더 중요하다.
어떤 개발자는 소스코드를 옆 팀, 심지어는 동료들도 안 보여준다. 보안 때문이라고 한다. 이런 경우 십중팔구 개발자가 철 밥그릇 지키려고 소스코드를 공개하지 않는 것이다.
우리 회사에서 소스코드가 중요하고 가치가 있는 이유는 이를 잘 아는 개발자들이 있기 때문이다. 소스코드 내용뿐만 아니라 소스코드를 이해하고 개발하는데 필요한 많은 지식과 경험이 있기 때문이다. 게다가 대부분의 소스코드는 다른 개발자가 이해하기 쉽게 잘 작성되지도 않는다.
보안이 중요하지 않다는 것이 절대로 아니다. 엉뚱한 방향으로 헛발질 하고 있는 것이 문제다. 물리적인 보안에 너무 치중하다가 정작 중요한 것을 놓치는 경우가 많다. 물리적인 보안도 신경을 써야 하지만 직원들의 의식 교육이 더 중요하다. 그리고 경영진들은 소프트웨어에 대한 이해를 좀더 높여야 한다. 어디 공장에서나 쓰일 법은 규칙을 소프트웨어 개발현장에 들이밀면 개발자들의 개발 효율성은 뚝 떨어진다. 하지만 개발은 엄청 불편하게 만들어 놓고 개발 시간을 더 주지 않는 것이 현실이다. 이는 결국 소프트웨어 품질의 저하로 이어지고 개발 문화의 후퇴를 가져온다.

이 글은 ZDNetKorea에 기고한 칼럼입니다.

2015년 6월 2일 화요일

외국에서 팔리는 소프트웨어의 아키텍처 디자인 원칙 (5)


김과장은 그 동안 한국어만 지원하는 소프트웨어 A를 개발해 왔는데 최근에 사장님이 A의 일본어 버전을 만들라고 했다. 그리고 개발 기간도 한달 밖에 주어지지 않았다. 그래서 기존 소스코드를 복사해서 한국어가 들어 있는 모든 부분을 일본어로 고치기 시작했다. 밤을 새워가며 고친 덕분에 일주일안에 모든 문장을 일본어로 수정할 수 있었다. 그래서 테스트를 포함하여 2주일만에 일본어버전을 뚝딱 만들어냈다. 빨리 개발했다고 사장님께 칭찬도 들었다. 

하지만 이렇게 한국어 버전과 일본어 버전의 소스코드가 따로 존재하다 보니 소스코드를 수정하려면 양쪽을 모두 고쳐야 했다. 그래서 개발시간은 기존보다 150%가 소요되었고, 나중에는 귀찮고 시간도 없어서 일본어 버전에는 최신 기능을 반영하지 못하게 되었다. 그러다가 치명적인 버그를 발견하면 양쪽을 모두 고쳤다. 한국어버전과 일본어버전 소스코드는 점점 달라지게 되었다.

그런 와중에 사장님이 중국어 버전도 만들라고 한다. 사장님은 김과장은 2주만 주면 뚝딱 만들어 낸다고 여기 저기 자랑을 하신다. 김과장은 또 소스코드를 복사해서 중국어 버전도 2주만에 만들었다. 이제 소스코드가 세벌이다. 뭘 하나 고쳐도 세 군데를 고쳐야 하는데 관리는 잘 안 된다. 소스코드가 엉망이 되서 관리가 안되는 것을 사장님은 잘모른다. 사장님이 유럽도 진출한다고 하는데 감당이 안돼서 퇴사할까 고민 중이다.

1. 소스코드 복사 

아래 그림과 같이 각 언어 버전 별로 소스코드를 제 각각으로 유지하는 방법으로 주위에서 흔히 볼 수 있다. 일단 소스코드를 복사하면 되돌아 올 수 없는 강을 건넌 것과 같다.



2. 별도의 Application

소스코드를 복사하는 것은 심각한 문제의 시작이기 때문에 국제화된 소프트웨어를 개발하더라도 소스코드를 하나로 유지하기 위한 노력은 꾸준히 되어 왔다. 두 번째 아키텍처는 기본적인 Application의 소스코드는 하나로 유지를 하면서 국제화 라이브러리와 지역화 라이브러리를 조합하여 지역화된 Application을 만드는 것이다.

기존에 Microsoft Office나 Windows에 적용되전 방식이다. 지금은 Microsoft도 바뀌었지만 예전에는 한국어, 일본어 버전을 따로 출시하였다. 물론 내부에서 개발할 때는 소스코드를 하나로 유지한다. 한국어, 일본어 지역화 라이브러리만 다를 뿐이다.

이런 아키텍처는 Application 개발자가 한국어의 특징이나 문화, 일본어의 특징이나 문화를 전혀 알 필요가 없다. 단지 국제화 라이브러리인 i18n library를 사용하기만 하면 된다. 그러면 각 버전에 맞게 다르게 동작하게 된다.

하지만 이 방식은 언어(로케일)별로 별도의 Application을 관리해야 하는 부담이 있다.


3. 하나의 소스코드, 하나의 Application

다음 아키텍처는 소스코드도 하나로 유지를 하고 하나의 Application만 출시를 하는 것이다. 언어(로케일) 설정을 바꾸기만 하면 해당 언어(로케일)로 출력되고 동작하는 것이다. 가장 권장되는 방식이면서 많은 소프트웨어가 사용하고 있다.

이 방식의 장점은 Application에서 국제화 관련 기능을 완전히 독립시킴으로써 Application 개발자의 부담을 덜었다. 그리고 L10n 라이브러리를 추가 장착만 함으로써 다양한 언어(로케일)을 추가로 지원할 수 있게 된다. 흔히 Language Pack이라고 부르기도 하는데 추가로 언어(로케일)를 지원한다고 제품을 다시 출시 하지 않아도 된다. 인터넷에서 Language Pack을 별도로 다운 받아서 설치하기만 하면 된다.

이런 아키텍처를 구성하려면 i18n library를 초기에 잘 만들어 놔야 한다. 언어(로케일)별로 다른 기능을 잘 추상화해서 미리 국제화 모듈을 만들어 놔야 한다. 나중에 고치려면 엄청나게 어렵다. 


먼저 한국어 버전만 만들고 나중에 다양한 언어(로케일)를 추가 지원하려는 계획을 가지고 있다면 어떻게 해야 할까? 그렇다고 대충 한국어 버전을 만들고 나중에 변경하려면 이미 망친 것이다. 미래에 국제화 계획이 있다면 아래 아키텍처처럼 한국어만 지원하더라도 국제화 라이브러리를 별도로 잘 만들어 놔야 한다. 처음에 이런 방식으로 개발하면 개발 시간이 10% 정도 더 들어간다. 하지만 나중에 여러 언어(로케일)를 지원할 때 몇 배, 몇 십 배의 시간이 절약된다.


물론 국제화 라이브러리를 제대로 만드는 것은 쉬운 일이 아니다. 웬만한 경험만으로 만드는 것은 매우 어렵다. 구조적으로도 어렵고 기능적으로도 어렵다. 또한, 입맛에 딱 맞게 만들어 놓은 상용라이브러리를 구하기도 어렵다. 필요한 회사나 개발자가 잘 설계를 해서 만들어야 한다. 

소프트웨어를 개발할 때는 항상 미리 국제화 계획을 검토해야 한다. 지금, 혹은 미래에 국제화 계획이 있다면 처음부터 국제화 아키텍처를 반영해야 한다. 그리고 소스코드는 무조건 한 벌을 유지해야 한다. 또한 Application도 하나로 유지를 해야 한다. 이런 대원칙에서 벗어나면 지옥을 맛보게 될 것이다. 그럼에도 지옥을 맛보지 못했다면 장사가 잘 안돼서 별 문제가 없었거나, 소프트웨어가 너무 작아서 어떻게 해도 별 문제가 안 되는 경우일 것이다. 

소프트웨어의 아키텍처는 항상 회사의 미래 전력을 내다봐야 하는 것이다. 오늘의 문제만 해결한다면 좋은 아키텍처라고 볼 수 었다.


이글은 네이버포스트에 게재한 글입니다.