Swift 2.1 [UInt8] --utf8--> String?

前端 未结 3 1779
小蘑菇
小蘑菇 2020-12-04 03:10

I know questions like this exist on both Stack Overflow and elsewhere. But it seems to have evolved a lot as well.

Given a list of UInt8 (a swift byte a

相关标签:
3条回答
  • 2020-12-04 03:41
    let buffUInt8: Array<UInt8> = [97, 98, 115, 100, 114, 102, 103, 104, 0]
    
    // you need Int8 array
    let buffInt8 = buffUInt8.map{ Int8(bitPattern: $0)}
    let str = String.fromCString(buffInt8) // "absdrfgh"
    

    alternatively you can use

    String.fromCStringRepairingIllFormedUTF8(cs: UnsafePointer<CChar>) -> (String?, hadError: Bool)
    
    0 讨论(0)
  • 2020-12-04 03:41

    I actually ended up needing to do this for a stream of UInt8 and was curious how hard utf8 decoding is. It's definitely not a one liner, but through the following direct implementation together:

    import UIKit
    
    let bytes:[UInt8] = [0xE2, 0x82, 0xEC, 0x00]
    
    var g = bytes.generate()
    
    extension String {
        init(var utf8stream:IndexingGenerator<[UInt8]>) {
            var result = ""
            var codepoint:UInt32 = 0
            while let byte = utf8stream.next() where byte != 0x00 {
                codepoint = UInt32(byte)
                var extraBytes = 0
                if byte & 0b11100000 == 0b11000000 {
                    extraBytes = 1
                    codepoint &= 0b00011111
                }
                else if byte & 0b11110000 == 0b11100000 {
                    extraBytes = 2
                    codepoint &= 0b00001111
                }
                else if byte & 0b11111000 == 0b11110000 {
                    extraBytes = 3
                    codepoint &= 0b00000111
                }
                else if byte & 0b11111100 == 0b11111000 {
                    extraBytes = 4
                    codepoint &= 0b00000011
                }
                else if byte & 0b11111110 == 0b11111100 {
                    extraBytes = 5
                    codepoint &= 0b00000001
                }
                for _ in 0..<extraBytes {
                    if let additionalByte = utf8stream.next() {
                        codepoint <<= 6
                        codepoint |= UInt32(additionalByte & 0b00111111)
                    }
                }
                result.append(UnicodeScalar(codepoint))
            }
            self = result
        }
    }
    
    String(utf8stream: g)
    
    0 讨论(0)
  • 2020-12-04 03:59

    Xcode 8 • Swift 3

    extension Collection where Iterator.Element == UInt8 {
        var bytes: [UInt8] { return Array(self) }
        var data: Data { return Data(self) }
        var string: String? { return String(data: data, encoding: .utf8) }
    }
    
    extension String {
        var data: Data { return Data(utf8) }
    }
    

    usage:

    let sentence = "Hello World"
    
    let utf8View = sentence.utf8
    let bytes = utf8View.bytes     // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
    
    let data1 = sentence.data
    print(data1 as NSData)         // <48656c6c 6f20576f 726c64>
    
    let data2 = utf8View.data
    let data3 = bytes.data
    let string1 = utf8View.string  // "Hello World"
    let string2 = bytes.string     // "Hello World"
    let string3 = data1.string     // "Hello World"
    
    0 讨论(0)
提交回复
热议问题