import Foundation extension Array { @inlinable init(reserveCapacity: Int) { self = [Element]() self.reserveCapacity(reserveCapacity) } @inlinable var slice: ArraySlice { self[startIndex ..< endIndex] } } public extension Array where Element == UInt8 { init(hex: String) { self.init(reserveCapacity: hex.unicodeScalars.lazy.underestimatedCount) var buffer: UInt8? var skip = hex.hasPrefix("0x") ? 2 : 0 for char in hex.unicodeScalars.lazy { guard skip == 0 else { skip -= 1 continue } guard char.value >= 48, char.value <= 102 else { removeAll() return } let v: UInt8 let c = UInt8(char.value) switch c { case let c where c <= 57: v = c - 48 case let c where c >= 65 && c <= 70: v = c - 55 case let c where c >= 97: v = c - 87 default: removeAll() return } if let b = buffer { append(b << 4 | v) buffer = nil } else { buffer = v } } if let b = buffer { append(b) } } func toHexString() -> String { lazy.reduce(into: "") { var s = String($1, radix: 16) if s.count == 1 { s = "0" + s } $0 += s } } } public extension Array where Element == UInt8 { func toBase64() -> String { Data(self).base64EncodedString() } init(base64: String) { self.init() guard let decodedData = Data(base64Encoded: base64) else { return } append(contentsOf: decodedData.bytes) } }