Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do i convert HexString To ByteArray in Swift 3

Tags:

swift

byte

swift3

I'm was trying to convert hexString to Array of Bytes([UInt8]) I searched everywhere but couldn't find a solution. Below is my swift 2 code

func stringToBytes(_ string: String) -> [UInt8]? {
    let chars = Array(string)
    let length = chars.count
    if length & 1 != 0 {
        return nil
    }
    var bytes = [UInt8]()
    bytes.reserveCapacity(length/2)
    for var i = 0; i < length; i += 2 {
        if let a = find(hexChars, chars[i]),
            let b = find(hexChars, chars[i+1]) {
            bytes.append(UInt8(a << 4) + UInt8(b))
        } else {
            return nil
        }
    }
    return bytes
} 

Example Hex

Hex : "7661706f72"

expectedOutput : "vapor"

like image 322
O-mkar Avatar asked Mar 11 '17 03:03

O-mkar


2 Answers

This code can generate the same output as your swift 2 code.

func stringToBytes(_ string: String) -> [UInt8]? {
    let length = string.characters.count
    if length & 1 != 0 {
        return nil
    }
    var bytes = [UInt8]()
    bytes.reserveCapacity(length/2)
    var index = string.startIndex
    for _ in 0..<length/2 {
        let nextIndex = string.index(index, offsetBy: 2)
        if let b = UInt8(string[index..<nextIndex], radix: 16) {
            bytes.append(b)
        } else {
            return nil
        }
        index = nextIndex
    }
    return bytes
}

let bytes = stringToBytes("7661706f72")
print(String(bytes: bytes!, encoding: .utf8)) //->Optional("vapor")
like image 165
OOPer Avatar answered Oct 09 '22 10:10

OOPer


Here is a sketch of how I'd do it in a more idiomatic Swift style (this might be Swift 4 only):

func toPairsOfChars(pairs: [String], string: String) -> [String] { 
    if string.count == 0 {
        return pairs
    } 
    var pairsMod = pairs
    pairsMod.append(String(string.prefix(2))) 
    return toPairsOfChars(pairs: pairsMod, string: String(string.dropFirst(2))) 
}

func stringToBytes(_ string: String) -> [UInt8]? {
    // omit error checking: remove '0x', make sure even, valid chars
    let pairs = toPairsOfChars(pairs: [], string: string)
    return pairs.map { UInt8($0, radix: 16)! }
}
like image 21
Sam King Avatar answered Oct 09 '22 12:10

Sam King