다운받은 깨진 한글 파일 이름 복구하기
Mon, Jul 23 2012 00:00:00Updated: 2020-01-04 22:25
인터넷에서 웹 브라우저로 파일을 받으면 서버 측의 잘못된 설정으로 인하여 한글 파일 이름이 이상하게 되는 경우가 많습니다.
cp949 코드가 utf-8 로 둔갑된 경우
사용자 컴퓨터 환경이 utf-8 환경이라면 그 파일 이름 자체가 utf-8 이기 때문에 iconv
, convmv
로도 복구가 안 됩니다. 이럴 경우 아래처럼 하면 복구가 됩니다. cp949(uhc)와 euc-kr 은 서로 다른
코드입니다. 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 인코딩된 파일 이름입니다.
참고 링크: https://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--독해비법(단락구조)장문독해"
아래는 디렉토리 내의 파일 이름을 고치는 소스입니다.
# coding: utf-8
def repair_cp949 utf8
begin
utf8.unpack("U*").pack("C*").force_encoding("cp949").encode("utf-8")
rescue Encoding::InvalidByteSequenceError
# FIXME
utf8
end
end
def repair_recursive dir
dirent = Dir.entries(dir) - [".", ".."]
dirent.each do |path|
if File.directory? path
path2 = repair_cp949(path)
`mv "#{path}" "#{path2}"` if path != path2
Dir.chdir path2
repair_recursive "."
Dir.chdir ".."
elsif File.file? path
path2 = repair_cp949(path)
`mv "#{path}" "#{path2}"` if path != path2
end
end
end
if ARGV.length.zero?
repair_recursive "."
else
repair_recursive ARGV[0]
end