如何在swift中将数据转换为十六进制字符串
我想要Swift中数据值的十六进制表示 最终,我想这样使用它:如何在swift中将数据转换为十六进制字符串,swift,swift3,Swift,Swift3,我想要Swift中数据值的十六进制表示 最终,我想这样使用它: let data = Data(base64Encoded: "aGVsbG8gd29ybGQ=")! print(data.hexString) 此代码使用计算属性扩展数据类型。它遍历数据字节,并将字节的十六进制表示形式连接到结果: extension Data { var hexDescription: String { return reduce("") {$0 + String(format: "%
let data = Data(base64Encoded: "aGVsbG8gd29ybGQ=")!
print(data.hexString)
此代码使用计算属性扩展
数据
类型。它遍历数据字节,并将字节的十六进制表示形式连接到结果:
extension Data {
var hexDescription: String {
return reduce("") {$0 + String(format: "%02x", $1)}
}
}
此代码使用计算属性扩展
数据
类型。它遍历数据字节,并将字节的十六进制表示形式连接到结果:
extension Data {
var hexDescription: String {
return reduce("") {$0 + String(format: "%02x", $1)}
}
}
一个简单的实现(取自,带有大写输出的附加选项)是
下面的实现速度快了大约50倍 (使用1000个随机字节进行测试)。它的灵感来自于 而且,但是利用 它是随Swift 5.3/Xcode 12推出的,可在macOS 11和iOS 14或更高版本上使用 此方法允许高效地从UTF-8单元创建Swift字符串,而无需进行不必要的复制或重新分配 此外,还提供了适用于较旧macOS/iOS版本的替代实现
extension Data {
struct HexEncodingOptions: OptionSet {
let rawValue: Int
static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
}
func hexEncodedString(options: HexEncodingOptions = []) -> String {
let hexDigits = options.contains(.upperCase) ? "0123456789ABCDEF" : "0123456789abcdef"
if #available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
let utf8Digits = Array(hexDigits.utf8)
return String(unsafeUninitializedCapacity: 2 * self.count) { (ptr) -> Int in
var p = ptr.baseAddress!
for byte in self {
p[0] = utf8Digits[Int(byte / 16)]
p[1] = utf8Digits[Int(byte % 16)]
p += 2
}
return 2 * self.count
}
} else {
let utf16Digits = Array(hexDigits.utf16)
var chars: [unichar] = []
chars.reserveCapacity(2 * self.count)
for byte in self {
chars.append(utf16Digits[Int(byte / 16)])
chars.append(utf16Digits[Int(byte % 16)])
}
return String(utf16CodeUnits: chars, count: chars.count)
}
}
}
扩展数据{
结构HexEncodingOptions:OptionSet{
让rawValue:Int
静态let大写=HexEncodingOptions(原始值:1字符串{
让hextdigits=options.contains(.大写)?“0123456789ABCDEF”:“0123456789ABCDEF”
如果可用(macOS 11.0、iOS 14.0、watchOS 7.0、tvOS 14.0、*){
让utf8Digits=数组(hextdigits.utf8)
返回字符串(unsafeUninitializedCapacity:2*self.count){(ptr)->Int in
var p=ptr.baseAddress!
对于自身中的字节{
p[0]=UTF8位[Int(字节/16)]
p[1]=utf8位[Int(字节%16)]
p+=2
}
返回2*self.count
}
}否则{
让utf16Digits=数组(hextdigits.utf16)
变量字符:[unichar]=[]
字符保留容量(2*自计数)
对于自身中的字节{
字符追加(UTF16位[Int(字节/16)])
字符追加(UTF16位[Int(字节%16)])
}
返回字符串(utf16CodeUnits:chars,count:chars.count)
}
}
}
一个简单的实现(取自,带有大写输出的附加选项)是
下面的实现速度快了大约50倍 (使用1000个随机字节进行测试)。它的灵感来自 而且,但是利用 它是随Swift 5.3/Xcode 12推出的,可在macOS 11和iOS 14或更高版本上使用 此方法允许高效地从UTF-8单元创建Swift字符串,而无需进行不必要的复制或重新分配 此外,还提供了适用于较旧macOS/iOS版本的替代实现
extension Data {
struct HexEncodingOptions: OptionSet {
let rawValue: Int
static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
}
func hexEncodedString(options: HexEncodingOptions = []) -> String {
let hexDigits = options.contains(.upperCase) ? "0123456789ABCDEF" : "0123456789abcdef"
if #available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
let utf8Digits = Array(hexDigits.utf8)
return String(unsafeUninitializedCapacity: 2 * self.count) { (ptr) -> Int in
var p = ptr.baseAddress!
for byte in self {
p[0] = utf8Digits[Int(byte / 16)]
p[1] = utf8Digits[Int(byte % 16)]
p += 2
}
return 2 * self.count
}
} else {
let utf16Digits = Array(hexDigits.utf16)
var chars: [unichar] = []
chars.reserveCapacity(2 * self.count)
for byte in self {
chars.append(utf16Digits[Int(byte / 16)])
chars.append(utf16Digits[Int(byte % 16)])
}
return String(utf16CodeUnits: chars, count: chars.count)
}
}
}
扩展数据{
结构HexEncodingOptions:OptionSet{
让rawValue:Int
静态let大写=HexEncodingOptions(原始值:1字符串{
让hextdigits=options.contains(.大写)?“0123456789ABCDEF”:“0123456789ABCDEF”
如果可用(macOS 11.0、iOS 14.0、watchOS 7.0、tvOS 14.0、*){
让utf8Digits=数组(hextdigits.utf8)
返回字符串(unsafeUninitializedCapacity:2*self.count){(ptr)->Int in
var p=ptr.baseAddress!
对于自身中的字节{
p[0]=UTF8位[Int(字节/16)]
p[1]=utf8位[Int(字节%16)]
p+=2
}
返回2*self.count
}
}否则{
让utf16Digits=数组(hextdigits.utf16)
变量字符:[unichar]=[]
字符保留容量(2*自计数)
对于自身中的字节{
字符追加(UTF16位[Int(字节/16)])
字符追加(UTF16位[Int(字节%16)])
}
返回字符串(utf16CodeUnits:chars,count:chars.count)
}
}
}
这并没有真正回答OP的问题,因为它工作在Swift字节数组上,而不是数据对象上。它比其他答案大得多。但它应该更有效,因为它避免使用字符串(格式:)
无论如何,希望有人能发现这有用
public class StringMisc {
// MARK: - Constants
// This is used by the byteArrayToHexString() method
private static let CHexLookup : [Character] =
[ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" ]
// Mark: - Public methods
/// Method to convert a byte array into a string containing hex characters, without any
/// additional formatting.
public static func byteArrayToHexString(_ byteArray : [UInt8]) -> String {
var stringToReturn = ""
for oneByte in byteArray {
let asInt = Int(oneByte)
stringToReturn.append(StringMisc.CHexLookup[asInt >> 4])
stringToReturn.append(StringMisc.CHexLookup[asInt & 0x0f])
}
return stringToReturn
}
}
测试用例:
// Test the byteArrayToHexString() method
let byteArray : [UInt8] = [ 0x25, 0x99, 0xf3 ]
assert(StringMisc.byteArrayToHexString(byteArray) == "2599F3")
这并不能真正回答OP的问题,因为它工作在一个Swift字节数组上,而不是一个数据对象。它比其他答案大得多。但它应该更有效,因为它避免使用字符串(格式:) 无论如何,希望有人能发现这有用
public class StringMisc {
// MARK: - Constants
// This is used by the byteArrayToHexString() method
private static let CHexLookup : [Character] =
[ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" ]
// Mark: - Public methods
/// Method to convert a byte array into a string containing hex characters, without any
/// additional formatting.
public static func byteArrayToHexString(_ byteArray : [UInt8]) -> String {
var stringToReturn = ""
for oneByte in byteArray {
let asInt = Int(oneByte)
stringToReturn.append(StringMisc.CHexLookup[asInt >> 4])
stringToReturn.append(StringMisc.CHexLookup[asInt & 0x0f])
}
return stringToReturn
}
}
测试用例:
// Test the byteArrayToHexString() method
let byteArray : [UInt8] = [ 0x25, 0x99, 0xf3 ]
assert(StringMisc.byteArrayToHexString(byteArray) == "2599F3")
我的版本。它比Martin R.接受的[原始]答案快10倍左右
公共扩展数据{
私有静态let hexAlphabet=Array(“0123456789abcdef”.unicodeScalars)
func hexStringEncoded()->String{
字符串(减少为:“.unicodeScalars){结果,值为
result.append(Self.hexAlphabet[Int(value/0x10)])
result.append(Self.hexAlphabet[Int(值%0x10)])
})
}
}
我的版本。它比Martin R.接受的[原始]答案快10倍左右
公共扩展数据{
私有静态let hexAlphabet=Array(“0123456789abcdef”.unicodeScalars)
func hexStringEncoded()->String{
字符串(减少为:“.unicodeScalars){结果,值为
result.append(Self.hexAlphabet[Int(value/0x10)])
result.append(Self.hexAlphabet[Int(值%0x10)])
})
}
}
Swift 4-从数据到十六进制字符串基于,但甚至更快一点
extension Data {
/// A hexadecimal string representation of the bytes.
func hexEncodedString() -> String {
let hexDigits = Array("0123456789abcdef".utf16)
var hexChars = [UTF16.CodeUnit]()
hexChars.reserveCapacity(count * 2)
for byte in self {
let (index1, index2) = Int(byte).quotientAndRemainder(dividingBy: 16)
hexChars.append(hexDigits[index1])
hexChars.append(hexDigits[index2])
}
return String(utf16CodeUnits: hexChars, count: hexChars.count)
}
}
Swift 4-从十六进制字符串到数据
我还添加了一个快速解决方案,用于将十六进制字符串转换为数据(基于a)
扩展字符串{
///此字符串中十六进制字节的数据表示形式。
func hexDecodedData()->数据{
//获取此字符串的UTF8字符
设字符=数组(utf8)
//将字节保留在UInt8数组中,并使用l