Last active
March 11, 2020 12:19
-
-
Save drrost/ba328c4ef6ee0f7f6e10c3e8eb13526c to your computer and use it in GitHub Desktop.
Hexdump Data object to String
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
private let kHexHeader = "87654321 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789abcdef\n" | |
private let kLineHeader = "00000000:" | |
private let kLineLength = 16 | |
extension Data { | |
func hexArray() -> String { | |
let array = [UInt8](self) | |
if array.isEmpty { | |
return "<data ojbect is empty>" | |
} | |
var result = "[" | |
let count = array.count | |
for i in 0 ..< count { | |
result += NSString(format: "0x%02X", array[i]) as String | |
if i != count - 1 { | |
result += ", " | |
} | |
} | |
result += "]" | |
return result | |
} | |
func hex() -> String { | |
let array = [UInt8](self) | |
if array.isEmpty { | |
return "<data ojbect is empty>" | |
} | |
var result = kHexHeader | |
let count = array.count | |
if count != 0 { | |
for i in 0 ... (count - 1) / kLineLength { | |
let inRange = range(for: i, count: count) | |
let slice: [UInt8] = [UInt8](array[inRange]) | |
result += line(for: slice, i) | |
} | |
} | |
return result | |
} | |
private func range(for i: Int, count: Int) -> ClosedRange<Int> { | |
let fristIndex = i * kLineLength | |
var length = kLineLength | |
if (count - i * kLineLength) < kLineLength { | |
length = count - i * kLineLength | |
} | |
let lastIndex = fristIndex + length - 1 | |
return fristIndex...lastIndex | |
} | |
private func line(for bytes: [UInt8], _ index: Int) -> String { | |
var fullLine = lineHeader(for: index) | |
fullLine += hexLine(bytes) | |
fullLine += readableLine(bytes) | |
return fullLine + "\n" | |
} | |
private func lineHeader(for index: Int) -> String { | |
String(format:"%08X:", index) | |
} | |
private func hexLine(_ bytes: [UInt8]) -> String { | |
var result = "" | |
for (i, byte) in bytes.enumerated() { | |
if i % 2 == 0 { | |
result += " " | |
} | |
result += String(format:"%02X", byte) | |
} | |
let fullLineLength = 40 | |
let spacesCount = fullLineLength - result.count + 2 | |
return result + String(repeating: " ", count: spacesCount) | |
} | |
private func readableLine(_ bytes: [UInt8]) -> String { | |
var result = bytes.reduce("", { $0 + ($1 > 31 && $1 < 127 ? String(format: "%c", $1) : ".") }) | |
let fullLineLength = 16 | |
let spacesCount = fullLineLength - result.count | |
result += String(repeating: " ", count: spacesCount) | |
return result | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment