2016-12-21 2 views
0

Ich schreibe einen Code, um koreanischen Text von Server mit codierten euc-kr koreanischen Encoder zu analysieren.Swift euc-kr koreanische Codierung funktioniert nicht. Aber funktioniert in Python

Wenn ich nur die gleiche Codierung in Python, funktioniert es wie erwartet. Aber wenn ich es wie folgt mache, funktioniert die Codierung nicht. Das Ergebnis ist nicht lesbar.

In Python:

string = u'안녕하세요.'.encode('eucKR') 

In Swift:

let encoding:UInt = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(
     CFStringEncodings.EUC_KR.rawValue)) 

let encodedData = "안녕하세요.".data(using: String.Encoding(rawValue: encoding))! 

Was ist der Unterschied zwischen diesen zwei Codierungen?

Im Folgenden finden Sie vollständige Quellcodes für Python und Swift. Ich steckte immer noch auf den Kodierungsteil. Ist das Problem mit Alamofire Post Anfrage verbunden?

Python:

import requests 
from pattern import web 

string = u'저는 내일 바빠서 학교에 못갑니다.'.encode('eucKR') 
r = requests.post("http://nlp.korea.ac.kr/~demo/dglee/komatag.php", data={'formradio1': '', 'formradio2': 'ems', 'textarea': string}) 
dom = web.Element(r.text) 
main = dom('tr') 
for item in main: 
    result = web.plaintext(item.source) 
    a = result.encode('ISO-8859-1') 
    t=a.decode('eucKR') 
    print(t) 

Swift:

override func viewDidLoad() { 

     let string: NSString = NSString(string: "안녕하세요") 
     let encodedEucKr = stringToEuckrString(stringValue: string as String) 
     print(encodedEucKr) 

     Alamofire.request("http://nlp.korea.ac.kr/~demo/dglee/komatag.php", method: .post, parameters: ["formradio1":"", "formradio2":"ems", "textarea": encodedEucKr], headers: nil).responseString { response in 

      switch(response.result) { 
      case .success(_): 
       if let data = response.result.value{ 
        print(response.result.value) 
       } 
       break 

      case .failure(_): 
       print(response.result.error) 
       break 

      } 
     } 

    } 


func stringToEuckrString(stringValue: String) -> String { 

    let encoding:UInt = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(
     CFStringEncodings.EUC_KR.rawValue)) 

    let encodedData = stringValue.data(using: String.Encoding(rawValue: encoding))! 

    let attributedString = try? NSAttributedString(data: encodedData, options:[:],  documentAttributes: nil) 

    if let _ = attributedString { 
     return attributedString!.string 
    } else { 
     return "" 
    } 
} 
+0

Wie haben Sie Ihre Ergebnisse überprüft? Soweit ich auf Mac getestet habe (Xcode 8.2.1 und Python 2.7.10) enthielten beide Ergebnisse genau die gleiche Bytefolge. – OOPer

+0

Können Sie herausfinden, was die Lösung für mein Problem wäre? Ich habe es für ungefähr 3 Stunden festgefahren. immer noch kein Glück. –

+0

Ihre Art, eine POST-Anfrage in EUC-KR zu senden, ist völlig falsch, aber im Moment habe ich nicht genug Zeit, um eine Antwort zu schreiben. Warte auf jemanden, der dir helfen kann (oder für mich später). Jetzt scheint Ihre Frage bereit zu sein, einen Weg zur Lösung Ihres Problems zu finden. – OOPer

Antwort

0

Es war nicht einfach aus zwei Gründen ...

  1. Senden von Formulardaten in EUC-KR gilt nicht als Standard-Compl in modernen Webtechnologien und Standards.

  2. Die von Ihrem Server gesendete Antwort ist irgendwie kaputt, dass Swift das Ergebnis nicht als gültigen EUC-KR-Text dekodieren kann.

    (Dies scheint ein Fehler des Server-Seite Code.)

Wie auch immer, wenn Sie Web-Formular basierend Anfrage an den Server in EUC-KR senden müssen:

  • erstellen Sie eine EUC-KR-Byte-Sequenz aus dem ursprünglichen Original
  • Prozent-entkommen es, Sie müssen es selbst tun
  • Setzen Sie alle Anfragen in einer HTTP-Anforderung Körper
  • In
  • richtigen Mime-Typ Header

Einige Details auf dem Server ab. Ich habe Alamofire nie benutzt, also weiß ich nicht, ob Alamofire solche Dinge unterstützt. Hier

zeige ich Ihnen ein Beispiel einer normalen URLSession mit:

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 
    sendRequest(string: "안녕하세요") 
} 

func sendRequest(string: String) { 
    let rawEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(CFStringEncodings.EUC_KR.rawValue)) 
    let encoding = String.Encoding(rawValue: rawEncoding) 

    let url = URL(string: "http://nlp.korea.ac.kr/~demo/dglee/komatag.php")! 
    var request = URLRequest(url: url) 
    request.httpMethod = "POST" 
    //Create an EUC-KR byte sequece 
    let eucKRStringData = string.data(using: encoding) ?? Data() 
    //Percent-escape, you need to do it by yourself 
    //(Though, most server accepts non-escaped binary data with its own rule...) 
    let eucKRStringPercentEscaped = eucKRStringData.map {byte->String in 
     if byte >= UInt8(ascii: "A") && byte <= UInt8(ascii: "Z") 
     || byte >= UInt8(ascii: "a") && byte <= UInt8(ascii: "z") 
     || byte >= UInt8(ascii: "0") && byte <= UInt8(ascii: "9") 
     || byte == UInt8(ascii: "_") || byte == UInt8(ascii: ".") || byte == UInt8(ascii: "-") 
     { 
      return String(Character(UnicodeScalar(UInt32(byte))!)) 
     } else if byte == UInt8(ascii: " ") { 
      return "+" 
     } else { 
      return String(format: "%%%02X", byte) 
     } 
    }.joined() 
    //In application/x-www-form-urlencoded format, you send data in a URL-query like format. 
    let paramString = "formradio1=&formradio2=ems&textarea=\(eucKRStringPercentEscaped)" 
    //As all non-ASCII characters are percent-escaped, .isoLatin1 works well here. 
    let bodyData = paramString.data(using: .isoLatin1)! 
    //Form data needs to be sent as a body of HTTP protocol. 
    request.httpBody = bodyData 
    //Mime type for usual form data is "application/x-www-form-urlencoded". 
    request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") 
    //URLRequest is ready and you can start dataTask here. 
    let task = URLSession.shared.dataTask(with: request) {data, response, error in 
     if let error = error { 
      print("Error:", error) 
     } 
     if let response = response { 
      print("Response:", response) 
     } 
     //The response may not be a valid EUC-KR, you need to decode it with acceptig invalid bytes. 
     if let data = data { 
      var result = "" 
      var i = 0 
      while i < data.count{ 
       let ch = data[i] 
       if ch < 0x80 { 
        result += String(Character(UnicodeScalar(UInt32(ch))!)) 
       } else if 
        i + 2 <= data.count, 
        let ch2 = String(data: data.subdata(in: i..<i+2), encoding: encoding) 
       { 
        result += ch2 
        i += 1 
       } else { 
        result += "?" 
       } 
       i += 1 
      } 
      print("Result:", result) 
     } 
    } 
    //Do not remember to resume the created task. 
    task.resume() 
    //And remember you should not do anything after you invoked an async task. 
} 

Wenn Ihre Server-Seite kann UTF-8-Anfragen und Antworten richtig handhaben, vor dem Code kann viel einfacher sein. Die Verwendung von EUC-KR in Web-Services ist irgendwie veraltet. Sie sollten UTF-8 bald annehmen.

+0

Oh mein Gott, du bist so genial. Vielen Dank für Ihre wertvolle Zeit, um mein Problem zu lösen. Es sieht so kompliziert aus. Ich würde es niemals selbst lösen. Danke dir nochmal. Ich weiß Server ist wirklich alt, aber es gibt nur einen Weg, um es für meine Anwendung zu verwenden. –

Verwandte Themen