일단, split_string 에서 중간에 정규표현식을 사용하여 쪼개는 과정을 생략하고, 단지 utf-8 -> 어떤 인코딩 -> utf-8 로 돌리는 것은 웬만하면 다 됩니다. "어떤 인코딩"이 , , , 여기에 각각 BE, LE 붙여가며 해 봤는데, 모듈과 모듈 다 스트링이 원래의 것으로 잘 나오더군요. 그런데 정규 표현식을 써서 쪼개기를 하려면, 제대로 쪼개지질 않더군요. 어떤 인코딩을 뭘로 지정해도... 이런 인코딩들의 경우는 정규표현식의 "."이 여전히 "1바이트"를 의미한다고 생각하고, $length 값을 2배로 곱해서 처리하게 했더니 그제서야 제대로 쪼개집니다. 아래의 표는 각각의 인코딩 이름을 두 개의 모듈을 써서, 한글 스트링, 일본어 스트링, 그리고 위키페디아에서 적당히 복사해 온 정체모를 언어 스트링을 split_string($str, 2) 를 거치게 했을 때의 결과입니다. (딱히 언어에 따라 다른 결과가 나오지는 않았습니다) {{{ Encode모듈 Text::Iconv모듈 UCS-2 ok ok UCS-2BE ok ok UCS-2LE ok ok UTF-16 error(주1) error(주5) UTF-16BE ok ok UTF-16LE ok ok UTF-32(주2) error(주3) error(주6) UTF-32BE ok ok UTF-32LE ok ok UTF-8 error(주4) error(주7) * 주1) UTF-16:Unrecognised BOM b098 at /usr/lib/perl5/5.8.5/i386-linux-thread-multi/Encode.pm line 162 * 주2) $lengh 값을 4배 곱한 후 처리 * 주3) 주1과 같은 에러, 명칭만 UTF-32 로 나옴 (utf-16과 utf-32의 경우는 스트링 앞에 바이트오더를 알려주는 BOM이란 게 붙는다는 설명으로 보아, 스트링을 둘로 쪼갠 후에 뒷쪽 부분에는 그 BOM이 안 붙은 상태라서 이렇게 되는듯 * 주4) 문자들마다 바이트 수가 다르므로, 제대로 쪼개지지 않음. * 주5) split_string 에 인자로 준 숫자보다 하나 적은 수의 문자를 세어서 쪼갬.(쪼갤 때 BOM도 두 바이트를 차지하기 때문인듯) * 주6) 주5)와 동일 * 주7) 아예 결과가 ("", "") 으로 나옴 }}}
{{{#!vim perl use Encode; $str = "\x{ac00}\x{b098}"; # "가나" in unicode open OUT, ">out_unicode.txt"; print OUT "$str\n"; close OUT; }}} 별도의 인코딩 없이 저 유니코드 표현을 그대로 파일에 찍으면 UTF-8로 출력하더군요. {{{ $ hexdump out_unicode.txt 0000000 b0ea eb80 9882 000a <- 가 %EA%B0%80 나 %EB%82%98 그런데 두 바이트씩 끊은 후 little endian 으로 저장한 듯 0000007 }}}
그 다음은, 온갖 인코딩을 바꿔가면서 파일에 저장 =.=;; {{{#!vim perl # Encode 모듈의 경우는, 저 펄의 유니코드 표현을 아래의 각 이름별로 encode에 넣은 후 출력 for $enc qw(EUC-KR UCS-2 UCS-2BE UCS-2LE UTF-16 UTF-16BE UTF-16LE UTF-32BE UTF-32LE UTF-8) { $str2 = encode($enc, $str); open OUT, ">out_$enc.txt"; print OUT "$str2\n"; close OUT; } # Text::Iconv 의 경우는, 펄의 내부 표현을 나타내는 이름이 뭔지 모르기 때문에 # 일단 utf-8 스트링을 지정한 후 그걸 아래의 각 이름별로 utf-8 -> $enc 변환 $str = "가나"; for $enc qw(EUC-KR UCS-2 UCS-2BE UCS-2LE UTF-16 UTF-16BE UTF-16LE UTF-32BE UTF-32LE UTF-8 UNICODE) { $converter = Text::Iconv->new("UTF-8", "$enc"); $str2 = $converter->convert($str); open OUT, ">conv_$enc.txt"; print OUT "$str2\n"; close OUT; } }}} {{{ Encode()를 사용하여 Text::Iconv()를 사용하여 펄 내부 표현을 각각의 인코딩으로 변환 UTF-8 스트링을 각각의 인코딩으로 변환 -------------------------------------------------------------------- out_EUC-KR.txt conv_EUC-KR.txt 0000000 a1b0 aab3 000a 0000000 a1b0 aab3 000a 0000005 0000005 (가 %B0%A1 나 %B3%AA 인데 두 바이트씩 순서가 바뀌어 저장) -------------------------------------------------------------------- out_UCS-2.txt conv_UCS-2.txt 0000000 00ac 98b0 000a 0000000 ac00 b098 000a 0000005 0000005 (둘이 다르다! Encode에서는 UCS-2BE로, Text::Iconv는 LE로 저장했음) (파일이 저장되면서 두 바이트씩 바이트 순서가 바뀌어 저장되는지, 눈으로 봤을때는 좌측이 LE처럼 보임 =.=;) -------------------------------------------------------------------- out_UCS-2BE.txt conv_UCS-2BE.txt 0000000 00ac 98b0 000a 0000000 00ac 98b0 000a 0000005 0000005 -------------------------------------------------------------------- out_UCS-2LE.txt conv_UCS-2LE.txt 0000000 ac00 b098 000a 0000000 ac00 b098 000a 0000005 0000005 -------------------------------------------------------------------- out_UTF-16.txt conv_UTF-16.txt 0000000 fffe 00ac 98b0 000a 0000000 feff ac00 b098 000a 0000007 0000007 (이것도 다르다! Encode는 UTF-16BE로, Text::Iconv는 LE로 저장했음) (BOM 마크가 좀 이상하다... Encode는 BE의 BOM인 0xFeFF 를 앞에 붙이고 그게 파일로 저장되면서 순서가 바뀌었다고 볼 수 있는데, Text::Iconv가 붙인 BOM은 해석이 안 됨. BE의 BOM인 0xFeFF가 순서 바뀜 없이 저장된 거라면 그 뒤의 따라오는 "가나"가 16LE.txt와 동일하게 구성된 것과 상충하고, LE의 BOM은 0xFFeF 이므로 순서를 바꾸면 ef ff 여야 한다. -_-???) -------------------------------------------------------------------- out_UTF-16BE.txt conv_UTF-16BE.txt 0000000 00ac 98b0 000a 0000000 00ac 98b0 000a 0000005 0000005 -------------------------------------------------------------------- out_UTF-16LE.txt conv_UTF-16LE.txt 0000000 ac00 b098 000a 0000000 ac00 b098 000a 0000005 0000005 -------------------------------------------------------------------- out_UTF-32BE.txt conv_UTF-32BE.txt 0000000 0000 00ac 0000 98b0 000a 0000000 0000 00ac 0000 98b0 000a 0000009 0000009 -------------------------------------------------------------------- out_UTF-32LE.txt conv_UTF-32LE.txt 0000000 ac00 0000 b098 0000 000a 0000000 ac00 0000 b098 0000 000a 0000009 0000009 -------------------------------------------------------------------- out_UTF-8.txt conv_UTF-8.txt 0000000 b0ea eb80 9882 000a 0000000 b0ea eb80 9882 000a 0000007 0000007 -------------------------------------------------------------------- * 이건 좀 특별한 케이스 out_unicode.txt conv_UNICODE.txt 0000000 b0ea eb80 9882 000a 0000000 feff ac00 b098 000a 0000007 0000007 (Encode의 경우는 \x{ac00}\{b098}을 그대로 출력했더니 UTF-8과 동일하게 저장됐고, Text::Iconv 의 경우는 "UTF-8"을 "UNICODE"로 변환시켰더니만 UTF-16과 동일하게 저장됐음) }}}
http://search.cpan.org/~dankogai/Encode-2.18/Unicode/Unicode.pm - perldoc Encode::Unicode 위 문서에 있는 내용에 따르면 * 이나 는 뒤에 "BE"또는 "LE"를 생략하면 => ** decode의 경우에는 BOM이 있는 지 체크해서 BOM이 있으면 그에 따라 처리하고, 없으면 루틴이 죽는다 ** encode의 경우에는 BE로 인코딩한후 제일 앞에 BE에 해당하는 BOM을 붙인다. * 단, 의 경우는 예외로, 이건 IANA 등에도 등록되어 있으며 의 alias이다. iconv 쪽에서는 어느 문서를 봐야 하는지 알수가 없어 못 찾았지만, 저 설명대로라면 이나 는 모듈은 제 맘대로 BE취급하고 는 LE 취급한다 싶군요. 그건 그러려니 하더라도, 만큼은 두 모듈이 공히 BE로 처리해줘야 할 텐데 Iconv 쪽은 LE로 처리하는 것이 의아합니다. 뭐 해결은 못해도... 일단 현재 상황은 정확히 알게 되었으니 만족해야겠고...
chcp 65001