1

我正在扫描一个用 Big5 编码的汉字的二维码。(主页概况)

有没有机会在 Swift 3 中正确解码这个字符串?

我在 GitHub 和这个SO question上找到了这个Objective-C 示例,但是 Swift 中没有和常量。kCFStringEncodingBig5_HKSCS_1999kCFStringEncodingBig


更新:

我找到了相应的 swift 变量,所以我现在尝试了以下方法:

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
    guard metadataObjects?.count ?? 0 > 0 else {
        return
    }
    guard let metadata = metadataObjects.first as? AVMetadataMachineReadableCodeObject, let code = metadata.stringValue else {
        return
    }
    let big5encoding = String.Encoding(rawValue: CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(CFStringEncodings.big5.rawValue)))
    print("Big5 encoded String: " + (String(data: code.data(using: .nonLossyASCII)!, encoding: big5encoding) ?? "?"))
}

输出:Big5 encoded String: \326\367\322\263\270\305\277\366

我怎样才能达到预期的输出Big5 encoded String: 主页概况


更新 2:

我的二维码似乎包含一些损坏的数据,所以我创建了一个新代码,这次内容肯定是一个 Big5 编码的字符串(Android 应用程序正确读取它)。内容是傳統

当我使用我的 iOS 应用程序扫描此代码时,metadata.stringValue 返回日语字符串カヌイホ

这到底是怎么回事???

4

1 回答 1

5

CFStringEncodings 在 Swift 3 中被定义为枚举值:

public enum CFStringEncodings : CFIndex {

    // ...    
    case big5 /* Big-5 (has variants) */
    // ...    
    case big5_HKSCS_1999 /* Big-5 with Hong Kong special char set supplement*/
    // ...    
}

所以你必须转换

CFStringEncodings -> CFStringEncoding -> NSStringEncoding -> String.Encoding

例子:

let cfEnc = CFStringEncodings.big5
let nsEnc = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(cfEnc.rawValue))
let big5encoding = String.Encoding(rawValue: nsEnc) // String.Encoding

然后big5encoding可用于 和 之间的String转换(NS)Data

在您的情况下,您有一个字符串,其中每个 unicode 标量对应于 Big5 编码的一个字节。然后以下应该工作:

// let code = "\u{00D6}\u{00F7}\u{00D2}\u{00B3}\u{00B8}\u{00C5}\u{00BF}\u{00F6}"
let bytes = code.unicodeScalars.map { UInt8(truncatingBitPattern: $0.value) }
if let result = String(bytes: bytes, encoding: big5encoding) {
    print(result)
}

或者,使用 ISO Latin 1 编码将 Unicode 代码点 U+0000 .. U+00FF 映射到字节 0x00 .. 0xFF 的事实:

if let data = code.data(using: .isoLatin1),
    let result = String(data: data, encoding: big5encoding) {
    print(result)
}
于 2017-05-19T07:30:27.370 回答