我有以下代码:
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
如何将hexString
转换回UInt8
个字节的相同数组?
我问的原因是因为我想通过加密的十六进制字符串与服务器通信,我需要将其转换回UInt8
字节数组,以将字符串解码为其原始形式。 / p>
答案 0 :(得分:22)
您可以将hexa字符串转换回UInt8数组,每两个六进制字符重复一次,并使用UInt8 radix 16初始化程序从中初始化UInt8:
extension StringProtocol {
var hexaToBytes: [UInt8] {
let hexa = Array(self)
return stride(from: 0, to: count, by: 2).compactMap { UInt8(String(hexa[$0...$0.advanced(by: 1)]), radix: 16) }
}
}
或
extension Collection where Element == Character {
var hexaToBytes: [UInt8] {
var last = first
return dropFirst().compactMap {
guard let char = last else {
last = $0
return nil
}
defer { last = nil }
return UInt8(String([char,$0]), radix: 16)
}
}
}
Swift 5或更高版本
我们可以使用新的Character属性hexDigitValue
extension Collection where Element == Character {
var hexaToBytes: [UInt8] {
var last = first
return dropFirst().compactMap {
guard
let lastHexDigitValue = last?.hexDigitValue,
let hexDigitValue = $0.hexDigitValue else {
last = $0
return nil
}
defer { last = nil }
return UInt8(lastHexDigitValue * 16 + hexDigitValue)
}
}
}
<强>游乐场:强>
let hexa = "e0696349774606f1b5602ffa6c2d953f"
let bytes = hexa.hexaToBytes // [224, 105, 99, 73, 119, 70, 6, 241, 181, 96, 47, 250, 108, 45, 149, 63]
答案 1 :(得分:2)
快速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]
答案 2 :(得分:0)
基于Leo Dabus的答案
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]