全局唯一标识(UID)-多种实现方案

本文介绍了几种实现全局唯一标识的方法,包括64位全局唯一ID(基于snowflake算法改造)、62进制字符串唯一ID和不同精度的32位唯一ID。这些方法在不同场景下保证了每秒内的唯一值,可用于各种分布式系统中的唯一标识生成。
摘要由CSDN通过智能技术生成

原文转自:http://www.tanjp.com (即时修正和更新)

目录

64位全局唯一标识

62进制字符串唯一ID

32位唯一ID(一年(388天)内的每秒内有128个唯一值)

32位唯一ID(一个月(48天)内的每秒内有1024个唯一值)

32位唯一ID(一周(12天)内的每秒内有4096个唯一值)


64位全局唯一标识

snowflake是用64位整型来表示一个序列号的,看上去和我们的时间戳很像,但是它的起始元年不是1970年,而是自定义的。然后时间戳里面只是记录下当前毫秒与自定义的元年时间差,这样起始就用不到64位的bit来记录整个时间戳,多出来的几位就可以做其他的事情,来看下面的结构:

00000.......000 00000 00000 000000000000
|___________| |___| |___| |__________|
            |               |        |              |
        42bit        5bit    5bit       12bit

参考snowflake算法改造:

00000.......000 0000000000 000000000000
|___________| |________| |__________|
            |                     |             |
        42bit              10bit      12bit

64位的全局唯一ID,保证在138年内的每1毫秒内有4095个唯一值。

第一部分 长度为42位,精确到毫秒级的自定义时间戳。当前时间戳减去指定时间开始的时间戳,最大可记录138年。

第二部分 长度为10位,根据不同业务ID做区分,取值范围[0,1023]。

第三部分 长度为12位,自增ID,取值范围[0,4095]。

C++代码实现:

class Uid64
{
public:
    	explicit Uid64(uint32 pn_1st_from_year = 2000, uint32 pn_2nd_business_id = 0);
    	uint64 generate(uint32 pn_2nd_business_id);
private:
    	uint32 mn_1st_from_year; //毫秒级时间
    	uint32 mn_2nd_business_id; //业务ID
    	uint32 mn_3rd_index; //自增
};
Uid64::Uid64(uint32 pn_1st_from_year, uint32 pn_2nd_business_id)
	: mn_1st_from_year(pn_1st_from_year)
	, mn_2nd_business_id(pn_2nd_business_id)
	, mn_3rd_index(0)
{
    namespace pt = boost::posix_time;
	if ( (mn_1st_from_year > pt::microsec_clock::universal_time().date().year())
		|| (mn_1st_from_year < 1970) )
	{
		mn_1st_from_year = 1970;
	}
	if (pn_2nd_business_id > 1023)
	{
		pn_2nd_business_id = 0;
	}
}
uint64	Uid64::generate(uint32 pn_2nd_business_id)
{
	namespace pt = boost::posix_time;
	mn_2nd_business_id = pn_2nd_business_id;
	if (mn_2nd_business_id > 1023)
	{
		mn_2nd_business_id = 0;
	}
	++mn_3rd_index;
	if (mn_3rd_index > 4095)
	{
		mn_3rd_index = 0;
	}
	pt::ptime now = pt::microsec_clock::universal_time();
	pt::ptime from_time(boost::gregorian::date(mn_1st_from_year, 1, 1));
	pt::time_duration time_span = now - from_time;
	uint64 zn_1st = time_span.total_milliseconds();
	uint64 zn_2nd = mn_2nd_business_id;
	uint64 zn_3rd = mn_3rd_index;
	uint64 zn_result = (zn_1st << 22) | (zn_2nd << 12) | zn_3rd;
	return zn_result;
}

测试例子:

void main()
{	
    const uint32 kLen = 100000;
	Uid64 zo_u64(2019, 1);
	uint64 zc_vec[kLen];
	for (u
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值