顺序ID转换随机唯一ID(递增ID转换无序随机ID)

本文探讨如何在分布式环境中生成无序的唯一ID,通过将顺序ID转换为随机ID来避免顺序性。介绍了一种方法,通过多维数组映射,使得数字在转换后看起来随机且不可预测,同时保持可逆性。此外,解决了位数缩短问题,确保转换后的ID保持原位数。
摘要由CSDN通过智能技术生成

顺序ID转换随机唯一ID

如何在分布式环境生成唯一顺序ID. 有很多解决方案. 自行搜索. 这里只说如何将一个顺序ID转换成无序ID.位数不变.

以下所说的位数.都是指数字个数. 6位数字 就是6个数字. (10进制自然数)

转换结果预览

原始ID结果
100000849360
100001747561
100002285392
100003727153
100004873934
100005825155

1 将一个数字. 转换成另外一个数字.

首先.要实现的. 就是将一个数字.转换成另外一个数字. 也是这篇文章的基础.
这里说的数字. 是10进制自然数. 数字都由0-9组成. 可以将一个数字看成是由0-9组成的字符序列.
建一个数组. 长度为10. 元素为 0-9. 随机. 例:

	array1 :={6, 9, 0, 3, 5, 8, 1, 2, 7, 4}

有这个数组之后, 我们就可以直接将数字转换成另外一个数字.
索引0 对应6. 那么就是将0转换成6.
如果想将数字还原,就是将6转换成0,那么需要将数组元素对应设置.

	revertArray1 := {2, 6, 7, 3, 5, 4, 0, 8, 5, 1} 

使用数值作为索引获取到的结果就是原有数值

我们确定 将一个数字. 通过如上方式,可以映射成另外一个数字. 并且是1对1. 可逆的.

2. 个位数递增.数字看起来还是顺续的.

考虑如下数字.
123450,123451,123452,
将每一位数字(每个数字)使用array1转换之后
903586,903589,903580,
这虽然看起来是随机的. 但是还能很容易猜到.
观察发现 前5位数字相同(都是90358). 因为原始数字都是12345
这个结果并不符合预期(想将有序转换为随机无序数字)

首先. 使用这种映射方式,是可逆的.1对1的.
因为前几位数字的相同. 导致相同的输出.
那我们就将前几位数字的映射换成其他的呢? 我们的原始数据是递增的.也就是说,每次都是先增加个位.然后增加10位,百位…
我们将array1 由1维数组, 变成2维数组. 1维对应个位数索引. 2维对应数字映射.这个转换时候,个位数字不变. 也就是说. 一个数字.个位之前的所有位数. 看成一个数字. 用映射方式改变.

	array1 :={
		{8, 5, 2, 9, 3, 7, 1, 0, 6, 4},
		{6, 7, 8, 4, 2, 3, 9, 0, 5, 1},
		{5, 7, 1, 0, 8, 9, 2, 4, 6, 3},
		{1, 6, 0, 4, 3, 2, 7, 5, 8, 9},
		{9, 3, 6, 8, 5, 0, 2, 7, 1, 4},
		{8, 5, 2, 9, 3, 7, 1, 0, 6, 4},
		{6, 7, 8, 4, 2, 3, 9, 0, 5, 1},
		{5, 7, 1, 0, 8, 9, 2, 4, 6, 3},
		{1, 6, 0, 4, 3, 2, 7, 5, 8, 9},
		{2, 1, 6, 8, 5, 7, 3, 9, 0, 4},
	}

输入123450,123451,123452, 个位数 0,1,2 不变. 前几位是 12345. 也就是说. 数字12345使用不同转换映射进行转换.
结果: 529370,784231,710892

考虑如果输入是 100001,100002 结果: 588881,766662. 这个结果. 好像还是和预期有点差异.

那么我们将array1转换成3维数组. 1维对应个位数索引. 3维对应数字映射. 增加的第二维. 用于位数.(个数)
原始: 1 0 0 0 0
位数: 1 2 3 4 5
位数1-5每一位 都使用不同的映射. (第二维)
这样 即使 2-5位 数字相同.我们也可以将数字映射成一个随机数字.

64位无符号整形 值为: 18,446,744,073,709,551,615 共20位(个)数字. 所以 第二维长度应该是19(个位,最低位我们不进行转换)

这里就不列举了.

3. 位数缩短了? 6位数字.变成5位数字

考虑数组 {2, 1, 6, 8, 5, 7, 3, 9, 0, 4},
输入数字8 结果是0,这个转换处于中间位是没有任何问题的.
但是 如果处于第一位. 例:80000
原始: 8 0 0 0 0
位数: 1 2 3 4 5
转换之后的结果是 0****. 这个并不符合预期. 我们的预期是输入几位,结果就是几位. 而且,位数少了之后,我们并没有办法还原数字.

那么我们需要一个新的数组. 来转换首位数字.(最高位的数字). 它不映射0. 例:

{0, 5, 4, 7, 6, 2, 1, 3, 9, 8},

伪代码

// 三维数组 1维对应个位.2维长度19.(索引18是不映射0的数组). 3维是映射数组
int8[10][19][10] randmap = {...}
// input 是输入的数值.
uint64 convert(uint64 input){
    // 取个位数作为1维索引
	uint64 id = input%10;
	// 输出个位不变
	// NOTE: 如果不想个位也有顺序,可以用另外一个一维数组. 做单独映射 out = randmap2[id]
	uint64 out = id;
	// 中间变量.
	uint64 mul = 10;
	uint64 num = 0;
	// 位数索引
	int index = 0;
	// 去除个位
	input = input/10;
	while( input > 0 ) {
		// 最高位
		if input < 10 {
			out += randmap[id][18][input]*mul;
			break;
		}
		// 中间位
		out += randmap[id][index][input%10]*mul;
		input = input/10;
		mul *= 10;
		index += 1;
		// 预防
		if index >= 18 {
			index = 0
		}
	}
	return out;
}

如果有数据还原需求. 请自行实现.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值