Admin | Write | GuestBook
[공지] 해당 블로그에 용건이 있으신 분께서는 http://blog.fore.kr/ 의 방명록(Guestbook)으로 부탁드립니다.
IE UTF-8 인코딩과 encodeURIComponent 의 이야기.
Category : Programming/Programming Talk | URL : | Written by 포레 ( 2015. 5. 25. 20:07 ) | 신고

 

 

 #문제 발견

 

[ 링크가 걸린 문자를 클릭하여 접속한 상태. ]

 

자주 애용하는 사이트 중 하나를 돌아다니던 중, 문자열이 깨지는 사태가 발생.

 

[ 링크가 걸린 문자에 마우스를 올려놓은 상태. ]

 

해당 링크가 걸려있는 부분에 마우스를 올려보니,

 

UTF-8 코딩이 되어있지 않은채 그대로 문자열이 삽입되어 있었다.

 

위의 경우 익플이 아닌 파폭이나 크롬의 경우 자동적으로 UTF-8 변환해주지만

 

익플의 경우 특별한 설정을 하지 않으면, 자동적으로 변환되지 않는다.

 

< Internet Explorer 쿼리문을 자동적으로 UTF-8 변환 전송 방법 > 

 

[ 익스플로어 인터넷 옵션 도구 탭 ]

 

위 그림의 빨간색 네모칸이 그려져 있는 부분이 체크되어 있는 상태에서 한번 재부팅하면 적용된다.

 

 

인터넷 옵션으로 간단하게 처리하면 되는데, '이걸 자바스크립트에서 어떻게 변환하는가 ?'

 

관심을 갖은게 문제의 발단이 되었다 -_- . . .

 

이의 해결책중 하나라 encodeURIComponent 함수를 쓰면 된다는 구글형님의 조언을 듣고

 

당장 실행에 옮기기로 했다.

 

 

 # 과정

 

 

 

 

 

[ 실험할 웹페이지 소스 ]

 

encodeURIComponent _Test.htm

[ 실험할 웹페이지 ]

 

[ 실행한 결과 ]

 

음 ? ? ? 뭔가 이상하다.

 

해당 웹페이지 소스 문자열은 UTF-8 로 적혀있고 정상적으로 출력되면

 

%[Hex] 로 출력될 문자열은 많아야 12개정도 나와야 한다.

( 한글 문자당 3bytes 라고 생각했을때 )

 

그런데, 위 화면에선 24개로 나오는거로 봐선 인코딩 상에 문제가 있다는걸 어렴풋 생각해볼 수 있다.

 

[ 웹 페이지 인코딩 ]

 

여기서 기본 인코딩(한국어)를 UTF-8로 바꾸면

 

[ 웹 페이지 인코딩 방식 변환 (한국어->UTF-8) ]

 

정상적으로 출력되는걸 확인할 수 있다.

 

 이 경우 페이지의 meta contents charset 을 utf-8 을 명확히 기재하지 않은 잘못이 있는데 

 

그렇다면, encodeURIComponent 함수 내부에선 어떻게 해석하기에 위와 같은 기묘한 결과를 내는걸까 ?

 

직접적으로 디버깅해보지 않아 아래의 답이 명확하다고 답하기 힘들지만 추측으로는 아래와 같다.

 

 

 < 가정 1 >

 Windows 기준으로 메시지를 출력하기 위해선 MessageBox 함수를 호출할 필요성이 있는데

 이를 Ansi 함수로 작성하게 되면, 한국어 외 타언어를 출력할 시 문자가 깨지는 사태가 발생하므로

 MessageBox는 반드시 '유니코드' 로 호출할 것이다.

 

 < 추측 흐름 >

 01. 문자열을 얻어옴.(페이지가 UTF-8의 경우 UTF-8 에 해당하는 문자열 Hex 를 얻어옴.)

 

 02. 해당 문자열(UTF-8)을 페이지 인코딩(한국어)에 맞추어 유니코드로 변환함.

 

 03. 유니코드로 변환된 문자열을 UTF-8 문자열(%[Hex])로 변환시킴.

 

 04. UTF-8 문자열을 다시 페이지 인코딩에 맞추어 유니코드로 변환함.

 

 05. MessageBoxW 을 호출하여 alert 을 호출함.

 

[ encodeURIComponent 으로 문자열을 변환 후 alert 호출까지의 추측 과정 ]

 

위 과정의 04,05 번의 경우엔 깨질 일이 없으니 01~03번을 기준으로

 

위 추측을 바탕으로 C언어로 작성해보았다.

 

 encodeURIComponent_01.cpp 

encodeURIComponent_01.exe

[ C언어를 통한 첫번째 실험 소스 및 실행 파일 ]

 

[ C언어를 통한 첫번째 실험 결과 ]

 

[ 이전 잘못된 인코딩(한국어)으로 인한 웹페이지 실행한 결과 ]

 

위 검은색 콘솔창과 잘못된 인코딩으로 출력된 메시지창의 값을 비교해보면

 

앞부분 3개까진 똑같이 들어간다.

 

여기서, 추측해볼 수 있는건, 추측과정의 01번하고 03번은 확실하게 맞다는 이야기가 된다.

 

그럼, 02번의 UTF-8 문자열을 유니코드로 변환시에 문제가 발생하고 있다는 이야기인데

 

이의 중간 과정을 알아보기 위헤 웹페이지 소스를 바꾸어보기로 했다.

 

 

[ 실험할 웹페이지 소스 ]

 

Alert_Test.htm

[ 실험할 웹페이지 ]

 

[ 실험한 결과 ]

 

여기서 살펴보기 전에 잠깐 한가지 짚어보자.

 

위 메시지 창이 추측 과정의 04~05번에 해당하듯, 유니코드가 정상적으로 변환되었으리라 라는 보장은 없다.

(직접 디버깅해보지 않았으니...)

 

하지만, 한가지 확인으로 신빙성을 조금은 높혀볼 수 있다.

 

C언어를 통한 실험을 했을 때 03번의 Hex 3개는 정확하게 맞아 들어갔고

 

이는 02번에 해당하는 유니코드 Hex 값의 2개는 정확하게 맞아 들어간다는 추측을 해볼 수 있다.

( 02번의 Hex 값 앞의 2개는 9B 5A, \u5A9B )

 

이 추측을 토대로 www.unicode.org 에서 제공하는 code charts 를 확인해보면

 

[ 유니코드 5A9B ]

 

비슷하게 생겼다. 이를 통해 신빙성은 조금은 높아졌다. 해볼만한 가치가 있다 !!! (야호!)

 

여기서, 조금더 분석을 해보기 위해 Alert Test 에 출력된 메시지 박스의 내용을 조금 분석해볼 필요가 있다.

 

위의 괴상한 문자를 추출해서 핵스로 출력하면 아래와 같은 결과가 나온다.

 

[ Alert Test 의 메시지 박스 내용을 추출한 문자열의 Hex 값 ]

 

여기서, 눈치 게임이 시작되는데, 뭔가 특정 패턴이 보인다.

 

Hex 문자열 사이에 'FD FF' 라는게 좀 많이 보인다.

 

이걸 분석해볼 가치가 있는가는 일단 추출한 Hex 문자열을 UTF-8 로 변환시켜볼 필요성이 있다.

 

 

[ 추출한 Hex 값의 내용을 UTF-8로 변환 ]

 

[ 이전 잘못된 인코딩(한국어)으로 인한 웹페이지 실행한 결과 ]

 

충분한 가치가 있다 !!!

(완전히 똑같다.)

 

IE 내부에선 어떤식으로 번역하고 있는가 Hex값을 분석해 볼 필요가 있다.

 

이를 분석하기 위해서 https://msdn.microsoft.com/en-us/goglobal/cc305154 를 참고하였다.

 

처음, UTF-8 페이지의 '가나다라'에 해당하는 Hex 문자열은

 

 EA B0 80 EB 82 98 EB 8B A4 EB 9D BC

[ "가나다라" UTF-8 문자열 Hex ]

 

이와 같다. 이를 MultiByteToWideChar 을 통해 처리하게 되면

 

 (EA B0) (80) (EB 82) (98 EB) (8B A4) (EB 9D) (BC 00)

[ MultiByteToWideChar 의 유니코드 인코딩 번역 방법 ]

 

위와 같이 처리되어, 위 msdn 페이지의 표에 없는 문자는 그 문자 그대로 2bytes 를 출력하고

( 예를 들어, 80 같은 경우, 80 00 와 같이 2bytes 를 사용한다. )

 

표에는 번호가 있으나 내부에 문자가 없는 경우엔 2bytes 로 3F 00 값을 가진 '?' 를 넣게 된다.

 

[ C언어를 통한 첫번째 실험 결과 ]

 

이를 기준으로 분석해보면 얼추 맞게 들어가고 있다는 이야기가 된다.

 

하지만, IE은 이와 같이 해석하지 않는다.

 

다시, msdn 을 통해 분석해보면

 

 (EA B0) (80 (EB) (82) 98) (EB (8B) A4) (EB (9D) BC) 

[ encodeURIComponent 의 유니코드 인코딩 번역 방법 ]

 

이와 같이 해석하게 되는데 이렇게 보면 보기 힘드므로 아래의 표와 같이 순서를 작성했다.

 

 01. EA B0
 02. 80 EB x
 03. EB 82 x
 04. 82 98
 05. EB 8B x
 06. 8B A4
 07. EB 9D x
 08. 9D BC 

[ encodeURIComponent 의 유니코드 인코딩 번역 방법 순서 ]

 

x 라고 표기된 부분은 해석 실패로 'FD FF' Hex 값을 갖게 되는 부분이다.

 

[ Alert Test 메시지 내용에서 추출한 Hex 값의 내용을 UTF-8로 변환 ]

 

위 내용을 분석한 바탕으로 C언어로 작성하게 되면

 

 

encodeURIComponent_Final.cpp

encodeURIComponent_Final.exe

[ C언어를 통한 마지막 실험 소스 및 실행 파일 ]

 

[ C언어를 통한 마지막 실험 실행 결과 ]

 

[ 이전 잘못된 인코딩(한국어)으로 인한 웹페이지 실행한 결과 ]

 

똑같이 맞아 떨어지는 것을 확인할 수 있다.

 

 # 결론

 

추측컨데, 이 문제는 encodeURIComponent 함수만이 아닐 것으로 보인다.

 

encodeURIComponent 와 같은 문자열을 다루는 함수를 사용시 조금 주의할 필요성이 있다고 본다.

 

Category
분류 전체보기 (605)
Notice (6)
Programming (79)
DISKER (1)
FSCH (7)
Caption (0)
Rest Time ! (443)
Hobby (64)
Tour (5)
Blind Post (0)
Recent Post
Recent Comment
Link
Calender
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total :
Today :
Yesterday :