我如何在Swift 3中将Hexstring转换为Bytearray



我正在尝试将hexstring转换为一组字节([uint8]),但我到处搜索但找不到解决方案。以下是我的Swift 2代码

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
} 

示例hex

hex:" 7661706f72"

enduretoutput:"蒸气"

此代码可以生成与您的 swift 2代码

的输出相同的输出
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")

这是我如何以更惯用的速度样式做它的草图(这可能仅是Swift 4):

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)! }
}

以下代码可能对您有帮助

extension String {
/// Create `Data` from hexadecimal string representation
///
/// This takes a hexadecimal representation and creates a `Data` object. Note, if the string has any spaces or non-hex characters (e.g. starts with '<' and with a '>'), those are ignored and only hex characters are processed.
///
/// - returns: Data represented by this hexadecimal string.
func hexadecimal() -> Data? {
    var data = Data(capacity: characters.count / 2)
    let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
    regex.enumerateMatches(in: self, options: [], range: NSMakeRange(0, characters.count)) { match, flags, stop in
        let byteString = (self as NSString).substring(with: match!.range)
        var num = UInt8(byteString, radix: 16)!
        data.append(&num, count: 1)
    }
    guard data.count > 0 else {
        return nil
    }
    return data
 }
}
extension String {
/// Create `String` representation of `Data` created from hexadecimal string representation
///
/// This takes a hexadecimal representation and creates a String object from that. Note, if the string has any spaces, those are removed. Also if the string started with a `<` or ended with a `>`, those are removed, too.
init?(hexadecimal string: String) {
    guard let data = string.hexadecimal() else {
        return nil
    }
    self.init(data: data, encoding: .utf8)
}
/// - parameter encoding: The `NSStringCoding` that indicates how the string should be converted to `NSData` before performing the hexadecimal conversion.
/// - returns: `String` representation of this String object.
func hexadecimalString() -> String? {
    return data(using: .utf8)?
        .hexadecimal()
}
 }
  extension Data {
/// Create hexadecimal string representation of `Data` object.
/// - returns: `String` representation of this `Data` object.
func hexadecimal() -> String {
    return map { String(format: "%02x", $0) }
        .joined(separator: "")
}
}

这样使用:

let hexString = "68656c6c 6f2c2077 6f726c64"
print(String(hexadecimalString: hexString))

let originalString = "hello, world"
print(originalString.hexadecimalString())

在搜索和思考之后,您是如何做的

func toByteArray( _ hex:String ) -> [UInt8] {
    // remove "-" from Hexadecimal
    var hexString = hex.removeWord( "-" )
    let size = hexString.characters.count / 2
    var result:[UInt8] = [UInt8]( repeating: 0, count: size ) // array with length = size
    // for ( int i = 0; i < hexString.length; i += 2 )
    for i in stride( from: 0, to: hexString.characters.count, by: 2 ) {
        let subHexStr = hexString.subString( i, length: 2 )
        result[ i / 2 ] = UInt8( subHexStr, radix: 16 )! // ! - because could be null
    }
    return result
}

extension String {
    func subString( _ from: Int, length: Int ) -> String {
        let size = self.characters.count
        let to = length + from
        if from < 0 || to > size {
            return ""
        }
        var result = ""
        for ( idx, char ) in self.characters.enumerated() {
            if idx >= from && idx < to {
                result.append( char )
            }
        }
        return result
    }
    func removeWord( _ word:String ) -> String {
        var result = ""
        let textCharArr = Array( self.characters )
        let wordCharArr = Array( word.characters )
        var possibleMatch = ""
        var i = 0, j = 0
        while i < textCharArr.count {
            if textCharArr[ i ] == wordCharArr[ j ] {
                if j == wordCharArr.count - 1 {
                    possibleMatch = ""
                    j = 0
                }
                else {
                    possibleMatch.append( textCharArr[ i ] )
                    j += 1
                }
            }
            else {
                result.append( possibleMatch ) 
                possibleMatch = ""
                if j == 0 {
                    result.append( textCharArr[ i ] )
                }
                else {
                    j = 0
                    i -= 1
                }
            }
            i += 1
        }
        return result
    }   
}

请参阅此视频,以了解我是如何做到的。 信用:Alltech

用neter语法将字符串转换为数据。

static func hexStringToData(string: String) -> Data {
    let stringArray = Array(string)
    var data: Data = Data()
    for i in stride(from: 0, to: string.count, by: 2) {
        let pair: String = String(stringArray[i]) + String(stringArray[i+1])
        if let byteNum = UInt8(pair, radix: 16) {
            let byte = Data([byteNum])
            data.append(byte)
        }
        else{
            fatalError()
        }
    }
    return data
}

最新更新