Ios 如何在Swift中将十六进制字符串转换为UInt8字节数组?

Ios 如何在Swift中将十六进制字符串转换为UInt8字节数组?,ios,swift,encryption,aes,Ios,Swift,Encryption,Aes,我有以下代码: var encryptedByteArray: Array<UInt8>? do { let aes = try AES(key: "passwordpassword", iv: "drowssapdrowssap") encryptedByteArray = try aes.encrypt(Array("ThisIsAnExample".utf8)) } catch { fatalError("Failed to initiate aes!"

我有以下代码:

var encryptedByteArray: Array<UInt8>?
do {
    let aes = try AES(key: "passwordpassword", iv: "drowssapdrowssap")
    encryptedByteArray = try aes.encrypt(Array("ThisIsAnExample".utf8))
} catch {
    fatalError("Failed to initiate aes!")
}

print(encryptedByteArray!) // Prints [224, 105, 99, 73, 119, 70, 6, 241, 181, 96, 47, 250, 108, 45, 149, 63]

let hexString = encryptedByteArray?.toHexString()

print(hexString!) // Prints e0696349774606f1b5602ffa6c2d953f
var encryptedByteArray:Array?
做{
让aes=尝试aes(键:“passwordpassword”,iv:“DrowsAspDrowsSAP”)
encryptedByteArray=尝试aes.encrypt(数组(“ThisIsAnExample”.utf8))
}抓住{
fatalError(“未能启动aes!”)
}
print(encryptedByteArray!)//Prints[224、105、99、73、119、70、6241、181、96、47、250、108、45、149、63]
设hextString=encryptedByteArray?.ToHextString()
打印(十六进制字符串!)//打印e0696349774606f1b5602ffa6c2d953f
如何将
hextstring
转换回相同的
UInt8
字节数组


我之所以问这个问题,是因为我想通过加密的十六进制字符串与服务器通信,我需要将其转换回包含
UInt8
字节的数组,以将字符串解码为其原始形式。

您可以将您的十六进制字符串转换回每两个十六进制字符迭代一次的UInt8数组,并初始化使用UInt8基数16初始值设定项从它获取UInt8:


编辑/更新:Xcode 14•Swift 5.1

extension StringProtocol {
    var hexaData: Data { .init(hexa) }
    var hexaBytes: [UInt8] { .init(hexa) }
    private var hexa: UnfoldSequence<UInt8, Index> {
        sequence(state: startIndex) { startIndex in
            guard startIndex < self.endIndex else { return nil }
            let endIndex = self.index(startIndex, offsetBy: 2, limitedBy: self.endIndex) ?? self.endIndex
            defer { startIndex = endIndex }
            return UInt8(self[startIndex..<endIndex], radix: 16)
        }
    }
}

操场:

let hexaString = "e0696349774606f1b5602ffa6c2d953f"

let bytes = hexaString.hexa   // [224, 105, 99, 73, 119, 70, 6, 241, 181, 96, 47, 250, 108, 45, 149, 63]

Swift 5

import CryptoSwift

let hexString = "e0696349774606f1b5602ffa6c2d953f"
let hexArray = Array<UInt8>.init(hex: hexString) // [224, 105, 99, 73, 119, 70, 6, 241, 181, 96, 47, 250, 108, 45, 149, 63]
import CryptoSwift
让hexString=“e0696349774606f1b5602ffa6c2d953f”
让hexArray=Array.init(hex:hexString)/[224、105、99、73、119、70、6241181、96、47、250、108、45、149、63]
根据

细节
  • Swift 5.1,Xcode 11.2.1
解决方案 全样本 不要忘记将解决方案代码粘贴到此处

控制台输出
有没有可能解释这部分代码:
.flatMap{UInt8(String)(hexa[$0..hexa是一个字符数组,我使用stride每两个字符迭代一次。$0表示子范围startIndex,而$0..advanced(by:2)是子范围endIndex。Uint8基数16将字符串转换为0到255之间的数字。最后一个问题。为什么我们用2而不是其他数字跨越字符?您需要将两个十六进制转换为1字节(0-9 a…f=0…15)16*16=256相关:。我尝试此操作时出现分段错误
import CryptoSwift

let hexString = "e0696349774606f1b5602ffa6c2d953f"
let hexArray = Array<UInt8>.init(hex: hexString) // [224, 105, 99, 73, 119, 70, 6, 241, 181, 96, 47, 250, 108, 45, 149, 63]
enum HexConvertError: Error {
    case wrongInputStringLength
    case wrongInputStringCharacters
}

extension StringProtocol {
    func asHexArrayFromNonValidatedSource() -> [UInt8] {
        var startIndex = self.startIndex
        return stride(from: 0, to: count, by: 2).compactMap { _ in
            let endIndex = index(startIndex, offsetBy: 2, limitedBy: self.endIndex) ?? self.endIndex
            defer { startIndex = endIndex }
            return UInt8(self[startIndex..<endIndex], radix: 16)
        }
    }

    func asHexArray() throws -> [UInt8] {
        if count % 2 != 0 { throw HexConvertError.wrongInputStringLength }
        let characterSet = "0123456789ABCDEFabcdef"
        let wrongCharacter = first { return !characterSet.contains($0) }
        if wrongCharacter != nil { throw HexConvertError.wrongInputStringCharacters }
        return asHexArrayFromNonValidatedSource()
    }
}
// Way 1
do {
     print("with validation: \(try input.asHexArray() )")
} catch (let error) {
     print("with validation: \(error)")
}

// Way 2
"12g". asHexArrayFromNonValidatedSource()
func test(input: String) {
    print("input: \(input)")
    do {
        print("with validation: \(try input.asHexArray() )")
    } catch (let error) {
        print("with validation: \(error)")
    }
    print("without validation \(input.asHexArrayFromNonValidatedSource())\n")
}

test(input: "12wr22")
test(input: "124")
test(input: "12AF")
input: 12wr22
with validation: wrongInputStringCharacters
without validation [18, 34]

input: 124
with validation: wrongInputStringLength
without validation [18, 4]

input: 1240
with validation: [18, 64]
without validation [18, 64]

input: 12AF
with validation: [18, 175]
without validation [18, 175]