Translate

2018년 7월 21일 토요일

다운받은 깨진 한글 파일 이름 복구하기

인터넷에서 웹 브라우저로 파일을 받으면 서버 측의 잘못된 설정으로 인하여 한글 파일 이름이 이상하게 되는 경우가 많다.

cp949 코드가 utf-8 로 둔갑된 경우


사용자 컴퓨터 환경이 utf-8 환경이라면 그 파일 이름 자체가 utf-8 이기 때문에 iconv, convmv 로도 복구가 안 된다.
이럴 경우 아래처럼 하면 복구가 된다.
cp949(uhc)와 euc-kr 은 서로 다른 코드이다. euc-kr ⊂ cp949 이다. cp949는 euc-kr을 확장한 코드이다.

# coding: utf-8
# irb 에서 다음을 입력하면 한글이 정상적으로 표시되는 것을 알 수 있다.
"ÇÁ·Î±×·¡¹Ö¾ð¾î·Ð".unpack("U*").pack("C*").force_encoding("euc-kr").encode("utf-8") #=> "프로그래밍언어론"

"ÇÁ·Î±×·¡¹Ö¾ð¾î·Ð".unpack("U*").pack("C*").force_encoding("cp949").encode("utf-8") #=> "프로그래밍언어론"

# 아래 함수(또는 메소드)를 이용하여 프로그램을 작성하면 된다.
def repair_cp949 utf8
    utf8.unpack("U*").pack("C*").force_encoding("cp949").encode("utf-8")
end

repair_cp949 "ÇÁ·Î±×·¡¹Ö¾ð¾î·Ð" #=> "프로그래밍언어론"



cp949 코드가 URL 인코딩된 상태로 다운로드된 경우


URL 인코딩된 파일 이름으로 다운로드되는 경우도 많다.
%B9%AB%B7%E1%C0%DA%B7%E14--SRS--%B5%B6%C7%D8%BA%F1%B9%FD(%B4%DC%B6%F4%B1%B8%C1%B6)%C0%E5%B9%AE%B5%B6%C7%D8.doc 이런 파일 이름이 URL 인코딩된 파일 이름이다.

참고 링크: http://en.wikipedia.org/wiki/Percent-encoding

이러한 파일 이름을 복구해보자.

irb를 열고 다음처럼 입력해본다.

irb(main):001:0> require 'uri'
=> true
irb(main):002:0> URI.unescape("%B9%AB%B7%E1%C0%DA%B7%E14--SRS--%B5%B6%C7%D8%BA%F1%B9%FD(%B4%DC%B6%F4%B1%B8%C1%B6)%C0%E5%B9%AE%B5%B6%C7%D8").unpack("C*").pack("U*")
=> "¹«·áÀÚ·á4--SRS--µ¶Çغñ¹ý(´Ü¶ô±¸Á¶)Àå¹®µ¶ÇØ"


위에서 설명한 ÇÁ·Î±×·¡¹Ö¾ð¾î·Ð 이러한 형태의 문자열이 출력되었다. 아래처럼 하면 사람이 알아볼 수 있는 정상적인 utf-8 문자열이 출력된다.

irb(main):026:0> URI.unescape("%B9%AB%B7%E1%C0%DA%B7%E14--SRS--%B5%B6%C7%D8%BA%F1%B9%FD(%B4%DC%B6%F4%B1%B8%C1%B6)%C0%E5%B9%AE%B5%B6%C7%D8").force_encoding("cp949").encode("utf-8")
=> "무료자료4--SRS--독해비법(단락구조)장문독해"


URL 인코딩된 깨진 한글 파일 이름을 고치는 메소드를 만들어보자.

require 'uri'

def repair_url_encoded_cp949 url_encoded_string
    URI.unescape(url_encoded_string).force_encoding("cp949").encode("utf-8")
end

repair_url_encoded_cp949 "%B9%AB%B7%E1%C0%DA%B7%E14--SRS--%B5%B6%C7%D8%BA%F1%B9%FD(%B4%DC%B6%F4%B1%B8%C1%B6)%C0%E5%B9%AE%B5%B6%C7%D8"
    #=> "무료자료4--SRS--독해비법(단락구조)장문독해"


아래는 def repair_cp949(utf8) 를 활용한 디렉토리 내의 파일 이름을 고치는 소스이다.

# coding: utf-8
require 'iconv'
require 'find'

def repair_cp949 utf8
    utf8.unpack("U*").pack("C*").force_encoding("cp949").encode("utf-8")
end

Find.find(".") do |path|
    if File.file? path
        path2 = repair_cp949(path)
        `mv "#{path}" "#{path2}"` if path != path2
    end
end

댓글 없음:

댓글 쓰기

응용 어플 끝글자 버그 잡는 거 진짜 개쉽습니다

그 동안 제가 끝글자 버그를 잡지 않고 방치한 이유 우선 책임, 의무가 없습니다. 제가 해당 어플 개발자도 아닐 뿐더러 오픈소스가 원래가 유지보수 의무, 보증 책임이 없습니다 . 이렇게 개떡 같은 게 오픈소스입니다. 전 과거 libhwp 하냐고...