Skip to content

Instantly share code, notes, and snippets.

@prachigauriar
Last active December 5, 2024 19:25
Show Gist options
  • Save prachigauriar/c9d22353aa2476d74c2ce77fe871bc39 to your computer and use it in GitHub Desktop.
Save prachigauriar/c9d22353aa2476d74c2ce77fe871bc39 to your computer and use it in GitHub Desktop.
ByteFormatStyle
import Foundation
struct ByteFormatStyle<Bytes> : FormatStyle, Hashable, Sendable where Bytes : Collection, Bytes.Element == UInt8 {
typealias FormatInput = Bytes
typealias FormatOutput = String
var radix: Int = 16
var uppercase: Bool = false
var groupingSeparator: String = " "
var groupingSize: Int = Int.bitWidth / 8
var secondaryGroupingSeparator: String = " "
var secondaryGroupingSize: Int = 2
var tertiaryGroupingSeparator: String = "\n"
var tertiaryGroupingSize: Int = 2
func radix(_ radix: Int, uppercase: Bool = false) -> Self {
var copy = self
copy.radix = radix
copy.uppercase = uppercase
return copy
}
func grouping(size: Int, separator: String = " ") -> Self {
var copy = self
copy.groupingSize = size
copy.groupingSeparator = separator
return copy
}
func secondaryGrouping(size: Int, separator: String = " ") -> Self {
var copy = self
copy.secondaryGroupingSize = size
copy.secondaryGroupingSeparator = separator
return copy
}
func tertiaryGrouping(size: Int, separator: String = "\n") -> Self {
var copy = self
copy.tertiaryGroupingSize = size
copy.tertiaryGroupingSeparator = separator
return copy
}
func format(_ value: Bytes) -> String {
let byteCharacterCount = String(UInt8.max, radix: radix).count
var formattedString = ""
var byteCount = 0
var primaryGroupCount = 0
var secondaryGroupCount = 0
for byte in value {
var byteString = String(byte, radix: radix, uppercase: uppercase)
let paddingCharacterCount = byteCharacterCount - byteString.count
if paddingCharacterCount > 0 {
byteString.insert(
contentsOf: String(repeating: "0", count: paddingCharacterCount),
at: byteString.startIndex
)
}
formattedString.append(byteString)
byteCount += 1
var appendPrimaryGroup = groupingSize > 0 && byteCount == groupingSize
if appendPrimaryGroup {
byteCount = 0
primaryGroupCount += 1
}
var appendSecondaryGroup = secondaryGroupingSize > 0 && primaryGroupCount == secondaryGroupingSize
if appendSecondaryGroup {
appendPrimaryGroup = false
primaryGroupCount = 0
secondaryGroupCount += 1
}
let appendTertiaryGroup = tertiaryGroupingSize > 0 && secondaryGroupCount == tertiaryGroupingSize
if appendTertiaryGroup {
appendSecondaryGroup = false
secondaryGroupCount = 0
}
if appendTertiaryGroup {
formattedString.append(tertiaryGroupingSeparator)
} else if appendSecondaryGroup {
formattedString.append(secondaryGroupingSeparator)
} else if appendPrimaryGroup {
formattedString.append(groupingSeparator)
}
}
return formattedString
}
}
let randomData = Data((0 ..< 128).map { _ in UInt8.random(in: .min ... .max) })
let formatStyle = ByteFormatStyle<Data>()
.radix(16, uppercase: true)
.grouping(size: 4, separator: " ")
.secondaryGrouping(size: 4, separator: " ")
.tertiaryGrouping(size: 2, separator: "\n")
print(formatStyle.format(randomData))
// 1616EC47 3BB6D892 85C86BBD 2841EBC8 6DD27D77 E1043EF9 EAD76A98 12720DC8
// 4F0D0F68 08578EDA B53D3517 39E93BAB 42D323BB 29A4FA9E 1DEDAC5F 29F3C92A
// 3BB5E5A3 3DCAF028 27A6D6D4 CCB492BA 53ED4C1F F1CF886A 9D9B0BAD A0C04AC8
// 10334DFB 74502BEF 836BC0FD 00E02605 83FFC261 0A4BB137 0D25068C 7B92421D
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment