11

I found how to convert hexa string into bytes [UInt8] but I have not found how to convert bytes [UInt8] into an hexa string in Swift

this hexstring convert to string code:

static func bytesConvertToHexstring(byte : [UInt8]) -> String {
    var string = ""

    for val in byte {
        //getBytes(&byte, range: NSMakeRange(i, 1))
        string = string + String(format: "%02X", val)
    }

    return string
}

samething like this result:

"F063C52A6FF7C8904D3F6E379EB85714ECA9C1CB1E8DFD6CA5D3B4A991269D60F607C565C327BD0ECC0985F74E5007E0D276499E1ADB4E0C92D8BDBB46E57705B2D5390FF5CBD4ED1B850C537301CA7E"

UInt8 array: [0, 11, 8, 15, 6, 6, 5, 8, 8, 4, 14, 14, 0, 0, 9, 12, 6, 4, 10, 6, 4, 8, 6, 2, 14, 2, 6, 13, 3, 3, 12, 4, 3, 12, 8, 13, 14, 4, 10, 1, 12, 15, 4, 0, 14, 14, 0, 8, 8, 14, 6, 15, 2, 2, 9, 15, 13, 6, 2, 6, 8, 15, 4, 2, 12, 1, 0, 13, 13, 4, 6, 0, 9, 6, 8, 2, 7, 0, 6, 1, 3, 3, 9, 15, 5, 7, 12, 8, 7, 5, 13, 14, 15, 6, 7, 6, 12, 6, 7, 7, 11, 9, 6, 0, 14, 5, 6, 14, 1, 5, 13, 10, 12, 13, 14, 2, 13, 14, 4, 7, 13, 0, 3, 10, 6, 11, 9, 12, 7, 11, 5, 3, 5, 11, 4, 9, 6, 10, 14, 0, 11, 7, 15, 9, 3, 14, 5, 1, 10, 14, 5, 6, 12, 4, 12, 14, 4, 3, 9, 8, 0]

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
Clever
  • 401
  • 1
  • 6
  • 17

4 Answers4

26

Xcode 11 • Swift 5.1 or later

extension StringProtocol {
    var hexa: [UInt8] {
        var startIndex = self.startIndex
        return (0..<count/2).compactMap { _ in
            let endIndex = index(after: startIndex)
            defer { startIndex = index(after: endIndex) }
            return UInt8(self[startIndex...endIndex], radix: 16)
        }
    }
}

extension DataProtocol {
    var data: Data { .init(self) }
    var hexa: String { map { .init(format: "%02x", $0) }.joined() }
}

"0f00ff".hexa                 // [15, 0, 255]
"0f00ff".hexa.data            // 3 bytes
"0f00ff".hexa.data.hexa       // "0f00ff"
"0f00ff".hexa.data as NSData  // <0f00ff>

Note: Swift 4 or 5 syntax click here

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • thanks answer but i need bytes array convert to string or hexstring convert to string. give me same example plz – Clever Nov 06 '15 at 05:21
  • 2
    Very elegant. Only thing better would be to add the reverse as well. – Roy Falk Mar 21 '16 at 11:52
  • Great but readability of the hex string would be better with spaces every 8 characters: `6162636465666768696a6b6c6d6e6f70` to `61626364 65666768 696a6b6c 6d6e6f70`. But I guess Swift hates hex displays. – zaph Jun 08 '16 at 11:56
  • I am aware of that and do use it. What I find interesting is that Apple has switched from hex to decimal in displaying data with Swift and for many cases that just does not work as well. – zaph Jun 09 '16 at 12:41
4

One liner:

testData.map{ String(format:"%02X", $0) }.joined(separator: " ")
Holger Bille
  • 2,421
  • 1
  • 16
  • 20
3

Thanks to Brian for his routine. It could conveniently be added as a Swift extension as below.

 extension Array where Element == UInt8 {
  func bytesToHex(spacing: String) -> String {
    var hexString: String = ""
    var count = self.count
    for byte in self
    {
        hexString.append(String(format:"%02X", byte))
        count = count - 1
        if count > 0
        {
            hexString.append(spacing)
        }
    }
    return hexString
}

}

Example of call:

let testData: [UInt8] = [15, 0, 255]
print(testData.bytesToHex(spacing: " "))          // 0F 00 FF
Daniel Mavrakis
  • 572
  • 10
  • 17
  • 1
    `map{ String(format:"%02X", $0 }.joined(separator: spacing)` one liner. Btw you could simply extend `DataProtocol`. Welcome to Swift! – Leo Dabus Dec 18 '21 at 14:31
-1

XCode 12-beta 6.

I know its late but I use this simple routine that gives an arbitrary spacing. I converted it from Java on Android. I also have C and other language versions of this - it easy to go from language to language when you cant remember all the language-specific libraries.

public static func bytesToHex(bytes: [UInt8], spacing: String) -> String
{
    var hexString: String = ""
    var count = bytes.count
    for byte in bytes
    {
        hexString.append(String(format:"%02X", byte))
        count = count - 1
        if count > 0
        {
            hexString.append(spacing)
        }
    }
    return hexString
}

It creates a two-digit hex string with an arbitrary spacing string between elements. I use it like this, for example, to display the results of a characteristic read

let charValue = [UInt8](characteristic.value ?? Data())
    print("Characteristic \(characteristic.uuid) read with value: \(Btle.bytesToHex(bytes: charValue, spacing: " "))")

with an output that looks like this:

Characteristic System ID read with value: 00 1C 05 FF FE FF E8 74

My experience with Swift and iOS is very limited; perhaps the seasoned Swift people can 'Swiftify' it.

Brian Reinhold
  • 2,313
  • 3
  • 27
  • 46