<br/> 前面介绍了雪花算法的理论基础,可以对大概的算法有个了解,但是细节上可能还是模糊,下面来说一下雪花算法中用到的位运算。这里先介绍两个,一个是:
<<
一个是
|
<< 的作用是将数字向左移动,这里的数字指的是二进制中的数,并不是字面上的长整型数字,当然移动后数字字面值肯定发生变化,但是这里对这个操作的主要理解要放在二进制数字向左移动上,而不是字面值扩大 2 的 n 次方倍。
“|”的作用是或运算,两个数对应的位上只要有一个是 1 就是 1,这样的官方解释不太明显,放在雪花算法中的作用就是合并数字,下面会详细演示。也就是说,三个需要生成的部分,分别由三个数来生成,然后利用 << 往左移动到对应的位置,最后将三个数字用 | 合并。这就是雪花算法中两个位移操作的作用。<br/><br/><br/><br/>
介绍一个例子比如有三个数字,分别打印出这三个数字的二进制形式:
<br/><center></center><br/>
可以看到,5 对应的二进制就是 101,8 对应的 2 进制就是 1000,10 对应的二进制就是 1010。这三个数字转换成二进制后,所有的 0 和 1 自然还是在最右边的末尾,下面就来进行位移操作 a 向左移动 20 位,b 向左移动 10 位,c 不变:
<br/><center></center><br/>
通过 a 和 b 位移结果的前后对比,可以发现在二进制的形式下,位移操作的意义浅显易懂,就是把代表值的所有数字向左移动了对应的位数。我们把雪花算法生成的数字也分成了三部分,这三部分可以分别按照规则生成,然后用 << 操作向左移动对应的位数,就可以到达对应的位置,最后再合并即可。<br/><br/><br/><br/>
来看一下合并的代码:
<br/><center></center><br/>
上面的“a|b|c”操作就是合并三个数字,怎么合并呢?就是多个 64 位的数字对应的合在一起,在这 64 中,只要对应位数上有一个位置是 1,合并后这个位上的数字就是 1,否则就是 0,根据这个结果,我们看到数字 d 的二进制形式确实包含了 abc 三个的所有数字。虽然最后的结果 d 是一个难以猜到的数字,但是我们进行位运算一定要看二进制,不要看整数字面值,这三个数字放在了各自对应的位数范围内,只要三个数字的范围不越界,也就是说 a 永远在从右向左 20 位以后,b 永远在 10 到 20 之间,c 永远在 0 到 10 之间,那么这三个数字就可以各管各的,并且结果是合法合理的。<br/><br/><br/>
当然这种操作也是有底线的,比如 b,他的数字大小转换成 2 进制后如果长度比 10 位大,那么它就会和 a 互相影响,导致结果不可预料,这就是范围的由来。我们再来考虑一下雪花算法,除了第一位 0 之外,第一部分是时间部分,占 41 位,也就是说生成的时间数字要向左移动(64-1-41=)22 位,第二部分是机器信息,占 10 位,也即是说代表机器信息的数字生成后要向左移动(64-1-41-10=)12 位,当然第三部分在末尾,就不用位移了。这三部分计算出来并且向左位移完成后,直接用“|”运算合成即可,就是我们最终要的分布式唯一 id。<br/><br/>
代码地址:https://gitee.com/blueses/sno… 02
<br/>