Swift에서 Unicde 정규화 문제 속편: HFS+와 일치성
9574 단어 Swift
HFS+의 Modified NFC
애플은 OS X에 파일 시스템HFS+을 적용해 원칙적으로 파일 이름을 NFD로 분해해 보관하고 있다.
두 가지 "가"가 분해 형식으로 통일되었다
예를 들어 사용자가 파일 이름が.txt
("가"가"가 U+304C의 한 문자)으로 파일을 저장하더라도 파일 시스템에서が.txt
("가"가"가 U+304B U+3099의 합성 문자)로 저장한다.
실제로 파일을 が.txt
("가"가"가 U+304C의 한 문자)로 저장한 후 Finder가 파일 이름 변경 모드에 들어가"가"라는 문자를 복사하면 U+304C가 아닌 U+304BU+3099 두 문자가 복사된 것을 확인할 수 있다.
→ 또는 (U+304B)+ 결합용 탁점(U+3099) 복제
CJK 호환 한자의 Modified NFC를 바꾸지 않음
이 정규화 형식은 언뜻 보면 보통 NFC인 것 같다.하지만 단순히 NFC로 분해하면 한자 달라지는 문제가 생긴다.
'new.txt'를 저장해도'신.txt'가 돼 실제 응용에 불편을 겪는다는 것이다.
이에 따라 애플은 HFS+ 정규화에서 유니코드 표준화 규격을 따르지 않고 CJK 호환 한자 등 정규화된 문자를 제외하고 독자적으로 정규화했다.이를 Modified NFC(정식 이름은 아니지만 따른다NAOI 권장 사항라고 합니다.
Modified NFC의 규격물야 선생의 해설에 관해서는 매우 통속적이고 알기 쉽게 총결하였다.
이 Modified NFC는 CJK 겸용 한자를 교체할 수 없고 두 가지'가오'가 통일되어 우리 일본인들에게 편리한 정규화 방식이다.그러나 애플이 Unicde 기술위원회에 이 건의를 했을 때부결되다는 이렇다.그 결과 이 모델ified NFC는 지금까지 표준화되지 않은 애플만의 정규화 형태로 바뀌었다.
Swift 문자열의 일관성
한편, 스위프트 문자열을 비교할 때 내부에서 발동하는 정규화는 일반적인 NFC나 NFC(어느 것인지 알 수 없음)로 CJK 호환 한자를 교체했다.
파일 시스템에서는 Modified NFC를 사용하지만 프로그래밍 언어에서는 NFD/NFC를 기본적으로 사용해 통합성이 좋은지 걱정된다.
하지만
한편, 스위프트 문자열을 비교할 때 내부에서 발동하는 정규화는 일반적인 NFC나 NFC(어느 것인지 알 수 없음)로 CJK 호환 한자를 교체했다.
파일 시스템에서는 Modified NFC를 사용하지만 프로그래밍 언어에서는 NFD/NFC를 기본적으로 사용해 통합성이 좋은지 걱정된다.
하지만
다음은 코드로 확인해 보겠습니다.
// テキストファイルの内容を読み込んで表示する関数
func printFile(filename : String) {
println(NSString(contentsOfFile: filename, encoding: NSUTF8StringEncoding, error: nil)!)
}
let gaC = "\u{304C}.txt" // 結合形の「が」
let gaD = "\u{304B}\u{3099}.txt" // 分解形の「が」
let 神 = "神.txt" // U+795E
let 神 = "神.txt" // U+FA19
let manager = NSFileManager.defaultManager()
if manager.fileExistsAtPath(gaC) {
println("結合形でヒットしました")
printFile(gaC) // が.txt の内容を表示
}
if manager.fileExistsAtPath(gaD) {
println("分解形でヒットしました")
printFile(gaD) // が.txt の内容を表示
}
神 == 神 // => true; 文字列としては同一と判定される
if manager.fileExistsAtPath(神) {
println("神は存在します")
printFile(神) // 神.txt の内容を表示
} else {
println("神は存在しません")
}
if manager.fileExistsAtPath(神) {
println("神は存在します")
printFile(神) // 神.txt の内容を表示
} else {
println("神は存在しません")
}
이 코드를 실행하면 파일 시스템은 어떤 "접근"을 사용하든 분할 형식으로 통일적으로 해석되고, 파일 시스템에 が.txt
존재하면 fileExistsAtPath(gaC)
와 fileExistsAtPath(gaD)
모두 진실로 판정된다.또한 동일한 파일が.txt
을 읽을 수 있습니다.반면 후반부
神.txt
와 神.txt
에서는 스위프트에서 문자열이 동일하다고 판정되지만 파일의 판정과 내용 읽기 측면에서는 별도로 처리된다.예를 들어 파일 시스템에
神.txt
神.txt
가 존재하지 않으면 상기 코드를 실행할 때神は存在しません
神は存在します
대화 상자.따라서 HFS+에 접근할 때 프로그래머가 기대한 결과를 먼저 얻었다고 할 수 있다.
잠재적인 버그의 온상이 될 수 있을까요?
그러나 문자열 비교에 포함된 정규화 현상은 잠재적인 오류를 초래할 수 있다.
예를 들어, 아마도 심심한 예일 것이다. 다음 코드.let adminName = "神"
// テキストファイルの内容を読み込んで表示する関数
func printFile(filename : String) {
println(NSString(contentsOfFile: filename, encoding: NSUTF8StringEncoding, error: nil)!)
}
func login(userName : String) {
if userName == adminName {
println("あなたは管理者ユーザです")
printFile(adminName + ".txt")
} else {
println("あなたは一般ユーザです")
printFile(userName + ".txt")
}
}
login("神")
네오 로그인으로 읽기神.txt
할 예정이지만 파일 시스템의 다른 파일神.txt
은 읽힌다.
이것은 정말 무섭다."Swift의 문자열은 비교적 무섭다"는 의식이 필요하다.
Reference
이 문제에 관하여(Swift에서 Unicde 정규화 문제 속편: HFS+와 일치성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/doraTeX/items/219d329e8a773e715631
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
let adminName = "神"
// テキストファイルの内容を読み込んで表示する関数
func printFile(filename : String) {
println(NSString(contentsOfFile: filename, encoding: NSUTF8StringEncoding, error: nil)!)
}
func login(userName : String) {
if userName == adminName {
println("あなたは管理者ユーザです")
printFile(adminName + ".txt")
} else {
println("あなたは一般ユーザです")
printFile(userName + ".txt")
}
}
login("神")
Reference
이 문제에 관하여(Swift에서 Unicde 정규화 문제 속편: HFS+와 일치성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/doraTeX/items/219d329e8a773e715631텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)