【问题标题】:Convert Int64 to UUID将 Int64 转换为 UUID
【发布时间】:2022-01-05 07:20:13
【问题描述】:

如何将 swift 的 Int64 转换为 UUID 并返回?由于UUID 是128 位,我想用零填充前64 位。

我可以从uuid_t 构造UUID,它是UInt8 的元组,通过移位和转换Int64 八次。

有没有更好的方法?

【问题讨论】:

  • 虽然您可以从 64 位值创建一个 128 位值,但您会拥有 UUID 吗?当然,这对你来说可能无关紧要。
  • @CRD 我正在使用 CXProvider,它使用 UUID 作为调用标识符,而我们在框架中使用 Int64。我需要将 CXProvider 的 id 映射到我们的 id。

标签: objective-c swift cocoa


【解决方案1】:

UUID 是 Foundation 类型 NSUUID 的 Swift 覆盖类型, 后者可以从字节缓冲区创建。用一点点 指针杂耍这也适用于 64 位整数:

let vals: [UInt64] = [0, 0x123456789abcdef]

let uuid = vals.withUnsafeBufferPointer {
    $0.baseAddress!.withMemoryRebound(to: UInt8.self, capacity: 16) {
         NSUUID(uuidBytes: $0) as UUID
    }
}

print(uuid) // 00000000-0000-0000-EFCD-AB8967452301

【讨论】:

    【解决方案2】:

    严格回答你的问题

    “最简单”的做法(不依赖CollectionTypeTuple的内存布局,也不需要NSUUID)是:

    extension UUID {
        init(number: Int64) {
            var number = number
            let numberData = Data(bytes: &number, count: MemoryLayout<Int64>.size)
    
            let bytes = [UInt8](numberData)
    
            let tuple: uuid_t = (0, 0, 0, 0, 0, 0, 0, 0,
                                 bytes[0], bytes[1], bytes[2], bytes[3],
                                 bytes[4], bytes[5], bytes[6], bytes[7])
    
            self.init(uuid: tuple)
        }
    
        var intValue: Int64? {
            let tuple = self.uuid
            guard tuple.0 == 0 && tuple.1 == 0 && tuple.2 == 0 && tuple.3 == 0 &&
                  tuple.4 == 0 && tuple.5 == 0 && tuple.6 == 0 && tuple.7 == 0 else {
                    return nil
            }
    
            let bytes: [UInt8] = [tuple.8, tuple.9, tuple.10, tuple.11,
                                  tuple.12, tuple.13, tuple.14, tuple.15]
    
            let numberData = Data(bytes: bytes)
    
            let number = numberData.withUnsafeBytes { $0.pointee } as Int64
    
            return number
        }
    }
    

    另外,您可能想要throw/fatalError 而不是返回nil

    创建有效的UUIDs

    为了完整起见(并使其实际上可以创建有效的 UUID),我添加了一种从 2 Int64 创建它的方法,并使用该方法重写了您的问题的答案:

    UUID 创建自 (Int64, Int64)

    extension UUID {
        init(numbers: (Int64, Int64)) {
            var firstNumber = numbers.0
            var secondNumber = numbers.1
            let firstData = Data(bytes: &firstNumber, count: MemoryLayout<Int64>.size)
            let secondData = Data(bytes: &secondNumber, count: MemoryLayout<Int64>.size)
    
            let bytes = [UInt8](firstData) + [UInt8](secondData)
    
            let tuple: uuid_t = (bytes[0], bytes[1], bytes[2], bytes[3],
                                 bytes[4], bytes[5], bytes[6], bytes[7],
                                 bytes[8], bytes[9], bytes[10], bytes[11],
                                 bytes[12], bytes[13], bytes[14], bytes[15])
    
            self.init(uuid: tuple)
        }
    
        var intTupleValue: (Int64, Int64) {
            let tuple = self.uuid
    
            let firstBytes: [UInt8] = [tuple.0, tuple.1, tuple.2, tuple.3,
                                       tuple.4, tuple.5, tuple.6, tuple.7]
    
            let secondBytes: [UInt8] = [tuple.8, tuple.9, tuple.10, tuple.11,
                                        tuple.12, tuple.13, tuple.14, tuple.15]
    
            let firstData = Data(bytes: firstBytes)
            let secondData = Data(bytes: secondBytes)
    
            let first = firstData.withUnsafeBytes { $0.pointee } as Int64
            let second = secondData.withUnsafeBytes { $0.pointee } as Int64
    
            return (first, second)
        }
    }
    

    UUIDInt64 创建(用 0 填充 MSB)

    extension UUID {
        init(number: Int64) {
            self.init(numbers: (0, number))
        }
    
        var intValue: Int64? {
            let (first, second) = intTupleValue
            guard first == 0 else { return nil }
    
            return second
        }
    }
    

    【讨论】:

    【解决方案3】:

    您也可以使用withUnsafeBytes 并将其加载为UUID

    let vals: [UInt64] = [0, 0x123456789abcdef]
    let uuid = vals.withUnsafeBytes { $0.load(as: UUID.self) }
    print(uuid) //  00000000-0000-0000-EFCD-AB8967452301
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-13
      • 1970-01-01
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 1970-01-01
      相关资源
      最近更新 更多