Challenge-response, SwiftData, new UI
This commit is contained in:
17
Sesame/API/Extensions/Data+Coding.swift
Normal file
17
Sesame/API/Extensions/Data+Coding.swift
Normal file
@ -0,0 +1,17 @@
|
||||
import Foundation
|
||||
|
||||
extension Data {
|
||||
|
||||
func convert<T>(into value: T) -> T {
|
||||
withUnsafeBytes {
|
||||
$0.baseAddress!.load(as: T.self)
|
||||
}
|
||||
}
|
||||
|
||||
init<T>(from value: T) {
|
||||
var target = value
|
||||
self = Swift.withUnsafeBytes(of: &target) {
|
||||
Data($0)
|
||||
}
|
||||
}
|
||||
}
|
42
Sesame/API/Extensions/Data+Hex.swift
Normal file
42
Sesame/API/Extensions/Data+Hex.swift
Normal file
@ -0,0 +1,42 @@
|
||||
import Foundation
|
||||
|
||||
extension Data {
|
||||
|
||||
public var hexEncoded: String {
|
||||
return map { String(format: "%02hhx", $0) }.joined()
|
||||
}
|
||||
|
||||
// Convert 0 ... 9, a ... f, A ...F to their decimal value,
|
||||
// return nil for all other input characters
|
||||
private func decodeNibble(_ u: UInt16) -> UInt8? {
|
||||
switch(u) {
|
||||
case 0x30 ... 0x39:
|
||||
return UInt8(u - 0x30)
|
||||
case 0x41 ... 0x46:
|
||||
return UInt8(u - 0x41 + 10)
|
||||
case 0x61 ... 0x66:
|
||||
return UInt8(u - 0x61 + 10)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public init?(fromHexEncodedString string: String) {
|
||||
let utf16 = string.utf16
|
||||
self.init(capacity: utf16.count/2)
|
||||
|
||||
var i = utf16.startIndex
|
||||
guard utf16.count % 2 == 0 else {
|
||||
return nil
|
||||
}
|
||||
while i != utf16.endIndex {
|
||||
guard let hi = decodeNibble(utf16[i]),
|
||||
let lo = decodeNibble(utf16[utf16.index(i, offsetBy: 1, limitedBy: utf16.endIndex)!]) else {
|
||||
return nil
|
||||
}
|
||||
var value = hi << 4 + lo
|
||||
self.append(&value, count: 1)
|
||||
i = utf16.index(i, offsetBy: 2, limitedBy: utf16.endIndex)!
|
||||
}
|
||||
}
|
||||
}
|
21
Sesame/API/Extensions/UInt32+Coding.swift
Normal file
21
Sesame/API/Extensions/UInt32+Coding.swift
Normal file
@ -0,0 +1,21 @@
|
||||
import Foundation
|
||||
|
||||
extension UInt32 {
|
||||
|
||||
/**
|
||||
Create a value from a little-endian data representation (MSB first)
|
||||
- Note: The data must contain exactly four bytes.
|
||||
*/
|
||||
init(data: Data) {
|
||||
let value = data.convert(into: UInt32.zero)
|
||||
self = CFSwapInt32LittleToHost(value)
|
||||
}
|
||||
|
||||
/// The value encoded to a little-endian representation
|
||||
var encoded: Data {
|
||||
Data(from: CFSwapInt32HostToLittle(self))
|
||||
}
|
||||
|
||||
/// The size of a `UInt32` when converted to data
|
||||
static let byteSize = MemoryLayout<UInt32>.size
|
||||
}
|
Reference in New Issue
Block a user