윈도우에서 압축한 zip파일, linux에서 한글이 깨질 때
윈도우에서 한글 이름으로 된 파일이나 폴더를 zip으로 압축하고, 리눅스에서 가져와서 압축을 푸는 경우, 한글이 깨질 때가 있습니다.
이유는 윈도우에서 한글 인코딩을 기본으로 MS949를 사용하고 있는데, 리눅스에서 인코딩이 UTF-8로 설정된 경우입니다.
리눅스의 인코딩 방식을 euckr로 설정하는 경우, 호환이 될 수도 있지만, 다국어처리 문제가 생기므로, UTF-8 방식을 권장합니다.
리눅스의 인코딩 방식을 먼저 확인합니다.
$ echo $LANG
을 하면 현재 인코딩 정보를 알 수 있습니다. 만약 UTF-8이 아닌 경우, .bash_profile 이나 기타 환경설정 파일에
export LANG=ko_KR.UTF-8
를 넣어줍니다.
압축을 풀기 위해 사용한 소스는 7-zip.org 의 linux 버전인 http://sourceforge.net/projects/p7zip/ 를 사용했습니다.
우선 최신 소스인 9.20.1 를 다운받습니다.
http://sourceforge.net/projects/p7zip/files/latest/download?source=files
$ tar xvjf p7zip_9.20.1_src_all.tar.bz2 cd p7zip_9.20.1 make
하게 되면, 기본적으로 bin/7za 라는 파일이 생깁니다. 하지만, 이 파일을 그대로 사용하게 되면, 한글이 깨져보이게 됩니다.
한글을 깨지지 않게 하려면 소스 파일 하나의 수정이 필요합니다.
$ vi p7zip_9.20.1/CPP/Common/StringConvert.cpp
#include "StdAfx.h" #include <stdlib.h>
아래에
#include <iconv.h> #include <errno.h>
를 추가
#ifdef LOCALE_IS_UTF8
위로..
#define LOCALE_IS_UTF8 static int iconv_wrapper(const char* p_from, const char* p_to, const char* p_src, char* p_dst) { if (p_src == NULL || p_dst == NULL) { return -210001; } size_t srclen; size_t dstlen; size_t inleftsize, outleftsize; size_t res; iconv_t cd = (iconv_t)-1; char* inptr = (char*)p_src; char* outptr = p_dst; cd = iconv_open(p_to, p_from); if (cd == (iconv_t)-1) { return -140005; } inleftsize = srclen = strlen(p_src); outleftsize = dstlen = inleftsize * 4; while (1) { res = iconv(cd, &inptr, &inleftsize, &outptr, &outleftsize); if (res == (size_t)-1) { if (errno == EILSEQ) { inptr++; inleftsize--; } else if (errno == EINVAL) { if (inleftsize <=2) { *outptr = '?'; outleftsize--; break; } } *outptr = '?'; outptr++; outleftsize--; inptr++; inleftsize--; } else break; } iconv_close(cd); if (dstlen-outleftsize <= 0) { return -210002; } p_dst[dstlen-outleftsize] = '\0'; return 0; }
아래 함수를 찾습니다. (같은 이름의 함수가 많으니, 함수 안의 내용을 확인하세요.
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) { if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) { UString resultString; bool bret = ConvertUTF8ToUnicode(srcString,resultString); if (bret) return resultString; }
아래와 같이 변경합니다.
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) { if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) { AString astr = srcString; int len = astr.Length(); char* p_a_str = astr.GetBuffer(len+1); char buf_utf8[65536] = {0,}; iconv_wrapper("UTF-8", "UTF-8", p_a_str, buf_utf8); if (strcmp(p_a_str, buf_utf8) != 0) iconv_wrapper("CP949", "UTF-8", p_a_str, buf_utf8); astr = buf_utf8; UString resultString; bool bret = ConvertUTF8ToUnicode(astr,resultString); if (bret) return resultString; }
다시 make 를 하고 bin/7za 를 사용하면 한글이 깨지지 않습니다~ ^_^
테스트 환경: CentOS 6.3 64bit, Ubuntu 12.10
각각의 환경에서 컴파일한 바이너리는 아래 링크에서 받을 수 있습니다.
https://dl.dropbox.com/u/2660823/7za_cent6_64.zip
https://dl.dropbox.com/u/2660823/7za_ubuntu1210.zip
참고 : 7za 사용방법
7za l test.zip : 리스트
7za x test.zip : 압축풀기
7za a test.zip file1 file2 dir1 dir2 : 압축하기
옵션
-ba 헤더 disable
-bd 퍼센트 disable
-aoa 덮어쓰기
-aou 새이름
-aos Skip
-oDIR output directory
-i@LISTFILE 파일목록












