@@ -58,4 +58,35 @@ extension String {
public func authenticate<A: Authenticator>(with authenticator: A) throws -> String {
return try self.utf8.lazy.map({ $0 as UInt8 }).authenticate(with: authenticator).toHexString()
}
+
+ private static var unicodeHexMap:[UnicodeScalar:UInt8] = ["0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,"a":10,"b":11,"c":12,"d":13,"e":14,"f":15]
+ /**
+ Converts the a hexadecimal string to a corresponding array of bytes.
+ So the string "ff00" would get converted to [255, 0].
+ - Returns: An array of 8 bit unsigned integers (bytes).
+ */
+ public func hexToBytes() -> [UInt8]{
+ var bytes:[UInt8] = []
+ var buffer:UInt8?
+ var skip = self.hasPrefix("0x") ? 2 : 0
+ for char in unicodeScalars.lazy {
+ guard skip == 0 else {skip -= 1;continue}
+ guard let value = String.unicodeHexMap[char] else {return []}
+ if let b = buffer {
+ let byte = b << 4 | value
+ bytes.append(byte)
+ buffer = nil
+ } else {
+ buffer = value
+ }
+ if let b = buffer{
+ bytes.append(b)
+ return bytes
@@ -62,6 +62,27 @@ final class ExtensionsTest: XCTestCase {
let hex = array.toHexString()
XCTAssertEqual(str, hex)
+ func testArrayInitHexPerformance(){
+ var str = "b1b2b3b3b3b3b3b3b1b2b3b3b3b3b3b3"
+ for _ in 0...9{
+ str += str
+ measure {
+ let _ = Array<UInt8>(hex: str)
+ func testhexToBytesPerformance(){
+ let _ = str.hexToBytes()
#if !CI