Merge pull request #6 from mufumade/master

Added initializer for specifying own random data
This commit is contained in:
Yasuhiro Hatta 2021-07-24 17:23:07 +09:00 committed by GitHub
commit 419d62778d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 0 deletions

View File

@ -35,6 +35,40 @@ public struct ULID: Hashable, Equatable, Comparable, CustomStringConvertible {
$0.copyBytes(from: data.dropFirst(4))
}
}
/// Creates a new ULID instance from a given timestamp and a random part that you provide
/// - Parameters:
/// - timestamp: -
/// - uuid: Data representation of the random part of the ULID
/// - Returns: **NIL** if the ULID is less than 80 bits or 10 bytes in size
public init?(timestamp: Date = Date(), uuid: Data){
let randomDataInBytes = 10
guard uuid.count >= randomDataInBytes else { return nil }
withUnsafeMutableBytes(of: &ulid) { (buffer) in
var i = 0
var millisec = UInt64(timestamp.timeIntervalSince1970 * 1000.0).bigEndian
withUnsafeBytes(of: &millisec) {
for j in 2 ..< 8 {
buffer[i] = $0[j]
i += 1
}
}
var randomPart:Data = Data()
if uuid.count > randomDataInBytes{
randomPart = uuid.prefix(randomDataInBytes)
}else{
randomPart = uuid
}
withUnsafeBytes(of: &randomPart) {
for j in 0 ..< 10 {
buffer[i] = $0[j]
i += 1
}
}
}
}
public init<T: RandomNumberGenerator>(timestamp: Date, generator: inout T) {
withUnsafeMutableBytes(of: &ulid) { (buffer) in

View File

@ -32,6 +32,55 @@ final class ULIDTests: XCTestCase {
XCTAssertEqual("01D0YHEWR9", actual.ulidString.prefix(10))
}
func testGenerateTimestampAndRandomnes(){
let timestamp = Date(timeIntervalSince1970: 1547213173.513)
let uuidCorrectSize: [UInt8] = [
0x01, 0x68, 0x3D, 0x17, 0x73, 0x09, 0x69, 0xF4, 0xA2, 0xB1
]
let actual = ULID(timestamp: timestamp, uuid: Data(uuidCorrectSize))!
XCTAssertEqual(timestamp, actual.timestamp)
XCTAssertEqual(0x01, actual.ulid.6)
XCTAssertEqual(0x68, actual.ulid.7)
XCTAssertEqual(0x3D, actual.ulid.8)
XCTAssertEqual(0x17, actual.ulid.9)
XCTAssertEqual(0x73, actual.ulid.10)
XCTAssertEqual(0x09, actual.ulid.11)
XCTAssertEqual(0x69, actual.ulid.12)
XCTAssertEqual(0xF4, actual.ulid.13)
XCTAssertEqual(0xA2, actual.ulid.14)
XCTAssertEqual(0xB1, actual.ulid.15)
//Test if initializer discards bytes beyond 10 bytes
let uuidTooBigSize: [UInt8] = [
0x01, 0x68, 0x3D, 0x17, 0x73, 0x09, 0x69, 0xF4, 0xA2, 0xB1, 0x99, 0x55
]
let actual2 = ULID(timestamp: timestamp, uuid: Data(uuidTooBigSize))!
XCTAssertEqual(timestamp, actual.timestamp)
XCTAssertEqual(0x01, actual2.ulid.6)
XCTAssertEqual(0x68, actual2.ulid.7)
XCTAssertEqual(0x3D, actual2.ulid.8)
XCTAssertEqual(0x17, actual2.ulid.9)
XCTAssertEqual(0x73, actual2.ulid.10)
XCTAssertEqual(0x09, actual2.ulid.11)
XCTAssertEqual(0x69, actual2.ulid.12)
XCTAssertEqual(0xF4, actual2.ulid.13)
XCTAssertEqual(0xA2, actual2.ulid.14)
XCTAssertEqual(0xB1, actual2.ulid.15)
let uuidTooSmallSize: [UInt8] = [
0x01, 0x68, 0x3D, 0x17, 0x73,
]
XCTAssertNil(ULID(timestamp: timestamp, uuid: Data(uuidTooSmallSize)))
}
func testGenerateRandomness() {
let timestamp = Date(timeIntervalSince1970: 1547213173.513)