一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何使用雪花算法生成真正的隨機數(shù)

麥辣雞腿堡 ? 來源:盼盼編程 ? 作者:盼盼編程 ? 2023-10-09 10:05 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

以前用rand和srand生成過偽隨機數(shù),偽隨機數(shù)的序列是固定的,今天學習生成真正的隨機數(shù)的生成。

熵池

利用/dev/urandom可以生成隨機數(shù)的值,/dev/urandomLinux下的熵池,所謂熵池就是當前系統(tǒng)下的環(huán)境噪音,描述了一個系統(tǒng)的混亂程度,環(huán)境噪音由這幾個方面組成,如內存的使用,文件的使用量,不同類型的進程數(shù)量等等。

利用/dev/urandom可以生成隨機數(shù)的值,/dev/urandomLinux下的熵池,所謂熵池就是當前系統(tǒng)下的環(huán)境噪音,描述了一個系統(tǒng)的混亂程度,環(huán)境噪音由這幾個方面組成,如內存的使用,文件的使用量,不同類型的進程數(shù)量等等。

#include < stdio.h >
#include < fcntl.h >


int main()
{
        int randNum = 0;
        int fd = 0;


    for(int i=0;i< 5;i++)
    {      
      fd = open("/dev/urandom", O_RDONLY);  
      read(fd, (char *)&randNum, sizeof(int));
      close(fd); 
      printf("randNum is %dn", randNum);
    }


        return 0;
}

運行結果:

mapan@mapan-virtual-machine:~/c++$ ./a.out 
randNum is 94961710
randNum is -523780773
randNum is 1542169420
randNum is -1632410867

每次打印的5個隨機數(shù)都不一樣,其實它的隨機性也不太好。雪花算法生成的數(shù)的隨機性很好,通常在分布式系統(tǒng)中生成唯一ID。

雪花算法

SnowFlake算法產生的ID是一個64位的整型,結構如下(每一部分用“-”符號分隔):
0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 00000000000

1位標識部分,在java中由于long的最高位是符號位,正數(shù)是0,負數(shù)是1,一般生成的ID為正數(shù),所以為0;

41位時間戳部分,這個是毫秒級的時間,一般實現(xiàn)上不會存儲當前的時間戳,而是時間戳的差值(當前時間-固定的開始時間),這樣可以使產生的ID從更小值開始;41位的時間戳可以使用69年,(1L << 41) / (1000L 60 60 24 365) = 69年;

10位節(jié)點部分,Twitter實現(xiàn)中使用前5位作為數(shù)據(jù)中心標識,后5位作為機器標識,可以部署1024個節(jié)點;

12位序列號部分,支持同一毫秒內同一個節(jié)點可以生成4096個ID;

/* 
    snowflake 


    ID 生成策略 
    毫秒級時間41位+機器ID 10位+毫秒內序列12位。
    0 41 51 64 +-----------+------+------+ |time |pc |inc | +-----------+------+------+ 
    前41bits是以微秒為單位的timestamp。
    接著10bits是事先配置好的機器ID。
    最后12bits是累加計數(shù)器。
    macheine id(10bits)標明最多只能有1024臺機器同時產生ID,sequence number(12bits)也標明1臺機器1ms中最多產生4096個ID, * 
      注意點,因為使用到位移運算,所以需要64位操作系統(tǒng),不然生成的ID會有可能不正確 
*/  


#include < stdio.h >  
#include < pthread.h >  
#include < unistd.h >  
#include < stdlib.h >  
#include < sched.h >  
#include < linux/unistd.h >  
#include < sys/syscall.h >  
#include < errno.h >  
#include< linux/types.h >  
#include< time.h >  
#include < stdint.h >  
#include < sys/time.h >  


struct  globle  
{  
    int global_int:12;  
    uint64_t last_stamp;  
    int workid;  
    int seqid;  
};  


void set_workid(int workid);  
pid_t gettid( void );  
uint64_t get_curr_ms();  
uint64_t wait_next_ms(uint64_t lastStamp);  
int atomic_incr(int id);  
uint64_t get_unique_id();
#include "snowflake.h"


struct globle g_info;


#define   sequenceMask  (-1L ^ (-1L < < 12L))  //L表示long型     4095


void set_workid(int workid)
{
 g_info.workid = workid;
}


pid_t gettid( void )//獲取線程ID
{
  return syscall( __NR_gettid );
}


uint64_t get_curr_ms()  //獲取毫秒
{
  struct timeval time_now;
  gettimeofday(&time_now,NULL);
  uint64_t ms_time =time_now.tv_sec*1000+time_now.tv_usec/1000;
  return ms_time;
}


uint64_t wait_next_ms(uint64_t lastStamp)
{
  uint64_t cur = 0;
  do {
    cur = get_curr_ms();
  } while (cur <= lastStamp);
  return cur;
}


int atomic_incr(int id)//累加
{
  __sync_add_and_fetch(&id, 1);
  return id;
}


uint64_t get_unique_id()
{
  uint64_t  uniqueId=0;
  uint64_t nowtime = get_curr_ms();//獲取當前毫秒數(shù)


  uniqueId = nowtime < < 22;   //填補時間戳部分


  //0x3ff 1023,二進制對應11 1111 1111 
  //100的二進制0000 0000 0000 0000 0000 0000 0110 0100
  //先執(zhí)行移位
  uniqueId |= (g_info.workid & 0x3ff) < < 12;   //填補節(jié)點部分


  if (nowtime < g_info.last_stamp)
  {
    perror("error");
    exit(-1);
  }


  if (nowtime == g_info.last_stamp)
  {
    //4095的二進制0000 1111 1111 1111      [long型]
    g_info.seqid = atomic_incr(g_info.seqid) & sequenceMask;
    if (g_info.seqid == 0)  //seqid=0防止沖突,修改時間
    {
      nowtime = wait_next_ms(g_info.last_stamp);//獲取大于當前時間的time
    }
  }
  else
  {
    g_info.seqid  = 0;
  }
  g_info.last_stamp = nowtime;


  uniqueId |= g_info.seqid;//填補序列號部分
  return uniqueId;
}


int main()
{
  set_workid(100);
  int i;
  for(i=0;i< 10;i++)
  {
    uint64_t unquie = get_unique_id();
    printf("pthread_id:%u, id [%llu]n",gettid(),unquie);
  }


  return;  
}

運行結果:

mapan@mapan-virtual-machine:~/c++$ ./a.out 
pthread_id:4970, id [6595660141600063488]
pthread_id:4970, id [6595660141600063489]
pthread_id:4970, id [6595660141600063490]
pthread_id:4970, id [6595660141600063491]
pthread_id:4970, id [6595660141600063492]
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)

    關注

    8

    文章

    7256

    瀏覽量

    91907
  • 算法
    +關注

    關注

    23

    文章

    4710

    瀏覽量

    95412
  • 序列
    +關注

    關注

    0

    文章

    70

    瀏覽量

    19853
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    如何使用MSP430內部時鐘生成隨機數(shù)

    ■TI公司 MSP430微控制器產品部Lane Westlund不管是生成隨機器件地址、強化加密算法還是創(chuàng)建獨立產品密鑰,可靠地生成隨機數(shù)
    發(fā)表于 07-12 06:20

    Kintex上的真隨機數(shù)生成器測試失敗的原因有哪些?

    我想在Kintex-7上生成真正隨機數(shù)。我正在關注Xilinx發(fā)表的論文,其中環(huán)形振蕩器用于隨機數(shù)生成,LHCA已被用作擾碼器。但是,每當我捕獲11兆字節(jié)的數(shù)據(jù)(真
    發(fā)表于 04-26 11:06

    如何去實現(xiàn)真正地單片機隨機數(shù)

    最近需要用到單片機隨機數(shù),但是用rand()產生的隨機數(shù),發(fā)現(xiàn)每次單片機上電時產生的隨機數(shù)都是一樣的,沒有實現(xiàn)真正隨機數(shù)。查資料發(fā)現(xiàn)要用到
    發(fā)表于 12-02 07:11

    用rand形成的不是真正隨機數(shù),怎么才能達到真正隨機?

    用rand形成的不是真正隨機數(shù)啊,,怎么才能達到真正隨機
    發(fā)表于 10-30 06:14

    神經(jīng)網(wǎng)絡的偽隨機數(shù)生成方法

    為了克服有限精度效應對混沌系統(tǒng)的退化影響,改善所生成隨機序列的統(tǒng)計性能,設計了一種新的基于六維CNN(細胞神經(jīng)網(wǎng)絡)的64 bit偽隨機數(shù)生成方法。在該方法中,通過控制六維CNN在每次
    發(fā)表于 02-02 15:49 ?0次下載

    隨機數(shù)生成算法

    在計算機上用數(shù)學的方法產生隨機數(shù)列是目前通用的方法,它的特點是占用的內存少,速度快.用數(shù)學方法產生的隨機數(shù)列是根據(jù)確定的算法推算出來的,嚴格說來并不是隨機的,因此一般稱用數(shù)學方法產生的
    發(fā)表于 04-03 10:25 ?6次下載

    C語言中隨機數(shù)生成代碼

    C語言中隨機數(shù)生成完整代碼:
    的頭像 發(fā)表于 02-20 09:21 ?1.1w次閱讀

    如何使用隨機數(shù)生成器來生成私鑰

    是偽隨機數(shù)生成器,它們都是由確定的算法,通過一個“種子”(比如“時間”),來產生“看起來隨機”的結果。
    發(fā)表于 03-18 10:40 ?5392次閱讀
    如何使用<b class='flag-5'>隨機數(shù)</b><b class='flag-5'>生成</b>器來<b class='flag-5'>生成</b>私鑰

    星系共識的隨機數(shù)生成算法對共識協(xié)議的作用

    基于PoW共識的區(qū)塊鏈系統(tǒng)由于挖礦的隨機性,以天然的方式為系統(tǒng)引入了熵,然而對于PoS和DPoS共識的區(qū)塊鏈系統(tǒng),就需要單獨設計一種方式去引入熵,那就是隨機數(shù)生成算法。可以說隨機數(shù)
    發(fā)表于 05-06 13:47 ?1081次閱讀

    如何利用SystemVerilog仿真生成隨機數(shù)

    采用SystemVerilog進行仿真則更容易生成隨機數(shù),而且對隨機數(shù)具有更強的可控性。對于隨機變量,在SystemVerilog中可通過rand或randc加數(shù)據(jù)類型的方式定義。ra
    的頭像 發(fā)表于 10-30 10:33 ?1.2w次閱讀
    如何利用SystemVerilog仿真<b class='flag-5'>生成</b><b class='flag-5'>隨機數(shù)</b>

    單片機STM32F1隨機數(shù)生成探索與實踐(基于CUBEMX和KEIL5)

    隨機數(shù)廣泛地用于游戲、以及測試環(huán)境中,本文產生的隨機數(shù)將用于測試排序算法性能。一些高端型號的單片機具有硬件的隨機數(shù)發(fā)生器,如STM32F4,STM32H7等,從這些單片機的
    發(fā)表于 12-31 19:12 ?12次下載
    單片機STM32F1<b class='flag-5'>隨機數(shù)</b><b class='flag-5'>生成</b>探索與實踐(基于CUBEMX和KEIL5)

    用于生成隨機數(shù)的電子骰子

    電子發(fā)燒友網(wǎng)站提供《用于生成隨機數(shù)的電子骰子.zip》資料免費下載
    發(fā)表于 07-06 10:58 ?4次下載
    用于<b class='flag-5'>生成</b><b class='flag-5'>隨機數(shù)</b>的電子骰子

    Arduino Lotto隨機數(shù)生成

    電子發(fā)燒友網(wǎng)站提供《Arduino Lotto隨機數(shù)生成器.zip》資料免費下載
    發(fā)表于 11-02 10:59 ?0次下載
    Arduino Lotto<b class='flag-5'>隨機數(shù)</b><b class='flag-5'>生成</b>器

    隨機數(shù)生成器開源分享

    電子發(fā)燒友網(wǎng)站提供《隨機數(shù)生成器開源分享.zip》資料免費下載
    發(fā)表于 11-11 11:57 ?0次下載
    <b class='flag-5'>隨機數(shù)</b><b class='flag-5'>生成</b>器開源分享

    技術分享 | 隨機數(shù)生成過慢導致系統(tǒng)阻塞怎么辦?

    原理linux上隨機數(shù)生成原理是將系統(tǒng)的中斷信息收集起來放入熵池中,通過算法生成更多無序的數(shù)據(jù),有了大量的無序數(shù)據(jù)之后,每次獲取隨機數(shù),就
    的頭像 發(fā)表于 08-15 09:20 ?3089次閱讀
    技術分享 | <b class='flag-5'>隨機數(shù)</b><b class='flag-5'>生成</b>過慢導致系統(tǒng)阻塞怎么辦?