前面介紹了雪花算法的理論基礎(chǔ),可以對大概的算法有個了解互订,但是細(xì)節(jié)上可能還是模糊叠赦,下面來說一下雪花算法中用到的位運算。這里先介紹兩個牲蜀,一個是:
<<
一個是
|
<<的作用是將數(shù)字向左移動笆制,這里的數(shù)字指的是二進(jìn)制中的數(shù),并不是字面上的長整型數(shù)字涣达,當(dāng)然移動后數(shù)字字面值肯定發(fā)生變化在辆,但是這里對這個操作的主要理解要放在二進(jìn)制數(shù)字向左移動上,而不是字面值擴(kuò)大2的n次方倍度苔。
?“|” 的作用是或運算匆篓,兩個數(shù)對應(yīng)的位上只要有一個是1就是1,這樣的官方解釋不太明顯寇窑,放在雪花算法中的作用就是合并數(shù)字鸦概,下面會詳細(xì)演示。也就是說甩骏,三個需要生成的部分窗市,分別由三個數(shù)來生成,然后利用 <<往左移動到對應(yīng)的位置饮笛,最后將三個數(shù)字用 | 合并咨察。這就是雪花算法中兩個位移操作的作用。
介紹一個例子比如有三個數(shù)字福青,分別打印出這三個數(shù)字的二進(jìn)制形式:
可以看到扎拣,5對應(yīng)的二進(jìn)制就是101,8對應(yīng)的2進(jìn)制就是1000,10對應(yīng)的二進(jìn)制就是1010。這三個數(shù)字轉(zhuǎn)換成二進(jìn)制后,所有的0和1自然還是在最右邊的末尾二蓝,下面就來進(jìn)行位移操作a向左移動20位誉券,b向左移動10位,c不變:
通過a和b位移結(jié)果的前后對比刊愚,可以發(fā)現(xiàn)在二進(jìn)制的形式下踊跟,位移操作的意義淺顯易懂,就是把代表值的所有數(shù)字向左移動了對應(yīng)的位數(shù)鸥诽。我們把雪花算法生成的數(shù)字也分成了三部分商玫,這三部分可以分別按照規(guī)則生成,然后用<<操作向左移動對應(yīng)的位數(shù)牡借,就可以到達(dá)對應(yīng)的位置拳昌,最后再合并即可。
來看一下合并的代碼:
上面的“a|b|c”操作就是合并三個數(shù)字钠龙,怎么合并呢炬藤?就是多個64位的數(shù)字對應(yīng)的合在一起,在這64中碴里,只要對應(yīng)位數(shù)上有一個位置是1沈矿,合并后這個位上的數(shù)字就是1,否則就是0咬腋,根據(jù)這個結(jié)果羹膳,我們看到數(shù)字d的二進(jìn)制形式確實包含了abc三個的所有數(shù)字。雖然最后的結(jié)果d是一個難以猜到的數(shù)字根竿,但是我們進(jìn)行位運算一定要看二進(jìn)制陵像,不要看整數(shù)字面值,這三個數(shù)字放在了各自對應(yīng)的位數(shù)范圍內(nèi)寇壳,只要三個數(shù)字的范圍不越界蠢壹,也就是說a永遠(yuǎn)在從右向左20位以后,b永遠(yuǎn)在10到20之間九巡,c永遠(yuǎn)在0到10之間,那么這三個數(shù)字就可以各管各的蹂季,并且結(jié)果是合法合理的冕广。
當(dāng)然這種操作也是有底線的,比如b偿洁,他的數(shù)字大小轉(zhuǎn)換成2進(jìn)制后如果長度比10位大撒汉,那么它就會和a互相影響,導(dǎo)致結(jié)果不可預(yù)料涕滋,這就是范圍的由來睬辐。我們再來考慮一下雪花算法,除了第一位0之外,第一部分是時間部分溯饵,占41位侵俗,也就是說生成的時間數(shù)字要向左移動(64-1-41=)22位,第二部分是機(jī)器信息丰刊,占10位隘谣,也即是說代表機(jī)器信息的數(shù)字生成后要向左移動(64-1-41-10=)12位,當(dāng)然第三部分在末尾啄巧,就不用位移了寻歧。這三部分計算出來并且向左位移完成后,直接用“|”運算合成即可秩仆,就是我們最終要的分布式唯一id码泛。