Skip to content

Instantly share code, notes, and snippets.

@DonaldHays
Created November 3, 2015 08:09
Show Gist options
  • Save DonaldHays/e5dc53c89e5abfe866f0 to your computer and use it in GitHub Desktop.
Save DonaldHays/e5dc53c89e5abfe866f0 to your computer and use it in GitHub Desktop.
A UUID type built in pure Swift
import Swift
/// `UUID` represents a 128-bit value suitable for uniquely identifying things.
public struct UUID: Hashable {
// MARK: -
// MARK: Public Properties
/// The raw bytes of the UUID.
public let data: Data
/// The UUID as a string.
///
/// The string will be formatted in the standard ASCII representation for a
/// UUID, for example 0DA9E5FB-433C-42DF-BA2E-9D89C8728DC6.
public var UUIDString: String {
var output = ""
for (index, byte) in data.enumerate() {
let nextCharacter = String(byte, radix: 16, uppercase: true)
if nextCharacter.characters.count == 2 {
output += nextCharacter
} else {
output += "0" + nextCharacter
}
if [3, 5, 7, 9].indexOf(index) != nil {
output += "-"
}
}
return output
}
public var hashValue: Int {
return data.hashValue
}
// MARK: -
// MARK: Lifecycle
/// Creates an instance of `UUID` representing a random RFC 4122 v4 UUID.
public init() {
var data = Data(count: 16)
data.withUnsafeMutableBufferPointer { uuid_generate_random($0.baseAddress) }
self.init(data: data)
}
/// Creates an instance of `UUID` with the specified data.
///
/// - precondition: `data` must be exactly 16 bytes long or a precondition
/// failure will be thrown.
public init(data: Data) {
precondition(data.count == 16, "UUID data must be 16 bytes in length")
self.data = data
}
/// Creates an instance of `UUID` with the specified UUID string.
///
/// The string must follow the standard ASCII representation for a UUID, for
/// example `2C4F4B46-776C-4643-9AA0-0129D79E140B`.
///
/// Returns `nil` for invalid strings.
public init?(UUIDString: String) {
// A UUID string must have 36 characters
guard UUIDString.characters.count == 36 else {
return nil
}
var data = Data(count: 16)
var index = UUIDString.startIndex
for i in 0 ..< 16 {
let string: String = UUIDString.substringWithRange(Range(start: index, end: index.advancedBy(2)))
index = index.advancedBy(2)
guard let byte = UInt8(string, radix: 16) else {
return nil
}
data[i] = byte
if [3, 5, 7, 9].indexOf(i) != nil {
index = index.successor()
}
}
self.data = data
}
}
public func == (lhs: UUID, rhs: UUID) -> Bool {
return lhs.data == rhs.data
}
@muescha
Copy link

muescha commented Mar 17, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment