在 Swift 中,将十六进制字符串转换为字节(或者更准确地说,是 UInt8 类型的数组)是一个常见的需求。这通常用于从数据包解析二进制数据或者将自定义的数据序列化为二进制形式。下面是一些将十六进制字符串转换为字节的实用方法。
1. 使用 Data 类型
Swift 中的 Data 类型可以直接将十六进制字符串转换为字节。
let hexString = "FF0A1F"
let data = Data(hexString: hexString)
if let byteArray = data?.bytes {
print(byteArray) // [255, 10, 31]
}
这里使用了自定义的 Data 类型的扩展,它有一个名为 hexString 的初始化方法。
extension Data {
init?(hexString: String) {
guard hexString.count.isMultiple(of: 2) else {
return nil
}
let hexData = Data(hexString.utf8)
self = Data(capacity: hexData.count / 2)
for (i, byte) in hexData.enumerated() {
self[i / 2] = (byte >> 4) | (byte << 4) & 0xFF
}
}
var bytes: [UInt8]? {
return map { $\0 }
}
}
2. 使用正则表达式
如果不想使用额外的扩展,可以通过正则表达式匹配十六进制数字,并转换为字节。
let hexString = "FF0A1F"
if let bytes = hexString.regexMatches?.map(UInt8.init) {
print(bytes) // [255, 10, 31]
}
// 辅助方法:使用正则表达式匹配十六进制字符串
extension String {
var regexMatches: [String]? {
do {
let regex = try NSRegularExpression(pattern: "(\\w{2})")
let matches = regex.matches(in: self, range: NSRange(location: 0, length: self.utf16.count))
return matches.map { String(self[Range($0.range, in: self)!]) }
} catch {
return nil
}
}
}
3. 使用 UInt8 数组直接转换
如果你确定十六进制字符串是有效的,可以直接将它们解析为 UInt8 类型的数组。
let hexString = "FF0A1F"
let bytes = [UInt8](repeating: 0, count: hexString.count / 2)
var hexBytes = Array(hexString.utf16)
for i in 0..<hexString.count / 2 {
bytes[i] = (UInt8(hexBytes[2 * i]) << 4) | (UInt8(hexBytes[2 * i + 1]))
}
print(bytes) // [255, 10, 31]
4. 使用第三方库
如果你的项目允许使用第三方库,可以考虑使用如 hexSwift 这样的库。
import hexSwift
let hexString = "FF0A1F"
let bytes = Data(hexString: hexString).toByteArray()
print(bytes) // [255, 10, 31]
总结
这几种方法都能将十六进制字符串转换为字节。选择哪一种取决于你的具体需求和项目的环境。如果你需要简洁和直接的方法,那么使用 Data 类型的扩展会是不错的选择。如果对性能有更高的要求,或者需要在更复杂的逻辑中转换,那么自定义解析可能会更加合适。
