从uuid时间戳到epoch后的秒数的转换似乎非常容易,这是基于规范的,也是基于cassandra基于其结构定义的c++驱动程序源代码的。
然而,当我尝试这样做时,我总是得到错误的值。我做错了什么,我不知道是什么。
为此,我使用了这里和这里提供的示例uuid值。
一个人要做的就是抢先一步 uint64_t
从uuid原始数据中,屏蔽其前四个msb,减去一个差,然后除以一个数。
下面是我的最小完整示例:
# include <boost/date_time.hpp>
# include <boost/uuid/uuid.hpp>
# include <boost/uuid/uuid_generators.hpp>
# include <boost/uuid/uuid_io.hpp>
# include <cstdint>
# include <iostream>
uint64_t TimestampFromUUID(const boost::uuids::uuid& uuid) {
static constexpr const int UUID_SIZE = 16;
static_assert(sizeof(uuid) == UUID_SIZE, "Invalid size of uuid");
static constexpr const int MS_FROM_100NS_FACTOR = 10000;
static constexpr const uint64_t OFFSET_FROM_15_10_1582_TO_EPOCH = 122192928000000000;
struct two64s {
uint64_t n1;
uint64_t n2;
} contents;
std::memcpy(&contents, uuid.data, UUID_SIZE);
// contents.n1 = __builtin_bswap64(contents.n1);
uint64_t timestamp = contents.n1 & UINT64_C(0x0FFFFFFFFFFFFFFF);
return (timestamp - OFFSET_FROM_15_10_1582_TO_EPOCH) / MS_FROM_100NS_FACTOR;
}
int main() {
std::cout << "Time now: " << (boost::posix_time::second_clock::universal_time() - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_milliseconds() << std::endl;
auto gen = boost::uuids::string_generator();
std::cout << "UUID: " << gen("49cbda60-961b-11e8-9854-134d5b3f9cf8") << std::endl;
std::cout << "Time from UUID: " << TimestampFromUUID(gen("49cbda60-961b-11e8-9854-134d5b3f9cf8")) << std::endl;
std::cout << "UUID: " << gen("58e0a7d7-eebc-11d8-9669-0800200c9a66") << std::endl;
std::cout << "Time from UUID: " << TimestampFromUUID(gen("58e0a7d7-eebc-11d8-9669-0800200c9a66")) << std::endl;
return 0;
}
该程序的输出为:
Time now: 1571735685000
UUID: 49cbda60-961b-11e8-9854-134d5b3f9cf8
Time from UUID: 45908323159150
UUID: 58e0a7d7-eebc-11d8-9669-0800200c9a66
Time from UUID: 45926063291384
你可以在这里玩这个源代码。
为什么我的结果甚至不接近当前的时间戳?我做错什么了?
2条答案
按热度按时间fnatzsnv1#
我知道你一直做得不好。在阅读您提供的文档时,我尝试从uuid重新生成时间戳。下面是我的代码:
ne5o7dgx2#
我认为将uuid处理为字符串并使用字符串操作来提取时间戳信息(然后将其转换为数值)更容易理解。诀窍在于时间戳信息存储在uuid中的方式。根据规范:
uuid字符串表示形式的正式定义由以下abnf[7]提供:
以下是uuid的字符串表示为urn的示例:
urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6
i、 e.uuid的第一部分(在“-”之前)是时间低,第二部分是时间中,第三部分是时间高版本,第一个字符是uuid版本。因此,我们需要拆分uuid并重新组合这些时间戳部分来创建完整的时间戳字符串,如下所示:{time high minus version}{time mid}{time low}
这是修改过的代码。我以这个漂亮的javascript示例作为参考:https://stackoverflow.com/a/26915856/3694234
输出