日韩在线首页I俄罗斯pornI男女猛烈激情XX00高潮动态I超碰免费97I乱人伦99久久I欧美日韩成人一区I最新日韩视频在线观看I粉嫩AV四季AV绯色AVI五月导航

×

從Linux內(nèi)核中獲取真隨機(jī)數(shù)

分類:互聯(lián)網(wǎng)熱點(diǎn) 編輯:it知事 瀏覽量:55
2020-07-13 16:55:23
內(nèi)核隨機(jī)數(shù)產(chǎn)生器 Linux內(nèi)核實(shí)現(xiàn)了一個(gè)隨機(jī)數(shù)產(chǎn)生器,從理論上說這個(gè)隨機(jī)數(shù)產(chǎn)生器產(chǎn)生的是真隨機(jī)數(shù)。與標(biāo)準(zhǔn)C庫中的rand(),srand()產(chǎn)生的偽隨機(jī)數(shù)不同,盡管偽隨機(jī)數(shù)帶有一定的隨機(jī)特征,但這些數(shù)字序列并非統(tǒng)計(jì)意義上的隨機(jī)數(shù)。也就是說它們是可重現(xiàn)的--只要每次使用相同的seed值,就能得到相同的偽隨機(jī)數(shù)列。通常通過使用time()的返回值來改變seed,以此得到不同的偽隨機(jī)數(shù)序列,但time()返回值的結(jié)果并不是不確定的(可預(yù)測),也就是這里仍然缺少一個(gè)不確定的噪聲源。對于需要真隨機(jī)數(shù)的程序,都不能允許使用偽隨機(jī)數(shù)。   為了獲得真正意義上的隨機(jī)數(shù),需要一個(gè)外部的噪聲源。Linux內(nèi)核找到了一個(gè)完美的噪聲源產(chǎn)生者--就是使用計(jì)算機(jī)的人。我們在使用計(jì)算機(jī)時(shí)敲擊鍵盤的時(shí)間間隔,移動(dòng)鼠標(biāo)的距離與間隔,特定中斷的時(shí)間間隔等等,這些對于計(jì)算機(jī)來講都是屬于非確定的和不可預(yù)測的。雖然計(jì)算機(jī)本身的行為完全由編程所控制,但人對外設(shè)硬件的操作具有很大的不確定性,而這些不確定性可以通過驅(qū)動(dòng)程序中注冊的中斷處理例程(ISR)獲取。內(nèi)核根據(jù)這些非確定性 的設(shè)備事件維護(hù)著一個(gè)熵池,池中的數(shù)據(jù)是完全隨機(jī)的。當(dāng)有新的設(shè)備事件到來,內(nèi)核會(huì)估計(jì)新加入的數(shù)據(jù)的隨機(jī)性,當(dāng)我們從熵池中取出數(shù)據(jù)時(shí),內(nèi)核會(huì)減少熵的估計(jì)值。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 asmlinkage int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,                             struct irqaction *action) {     int status = 1;     int retval = 0;           if (!(action->flags & SA_INTERRUPT))         local_irq_enable();       do     {         status |= action->flags;         retval |= action->handler(irq, action->dev_id, regs);         action = action->next;     }while (action);           if (status & SA_SAMPLE_RANDOM)         add_interrupt_randomness(irq);       local_irq_disable();     return retval; } 上面這段代碼是x86上用來處理某條中斷線上注冊的ISR例程的函數(shù)。這里我們感興趣的地方是:如果ISR在注冊期間指定了SA_SAMPLE_RANDOM標(biāo)志,在處理完action后,還要調(diào)用add_interrupt_randomness()這個(gè)函數(shù),它使用中斷間隔時(shí)間為內(nèi)核隨機(jī)數(shù)產(chǎn)生器產(chǎn)生熵。內(nèi)核就是在這里為熵池填充新數(shù)據(jù)的。 如果我們完全不操作計(jì)算機(jī)會(huì)如何呢?也就是作為噪聲源的產(chǎn)生者,我們完全不去碰鍵盤,鼠標(biāo)等外設(shè),不讓熵池獲得新的數(shù)據(jù),這個(gè)時(shí)候如果去熵池取數(shù)據(jù)內(nèi)核會(huì)如何反應(yīng)? 內(nèi)核在每次從熵池中取數(shù)據(jù)后都會(huì)減少熵的估計(jì)值,如果熵估計(jì)值等于0了,內(nèi)核此時(shí)可以拒絕用戶對隨機(jī)數(shù)的請求操作。 獲取內(nèi)核隨機(jī)數(shù) 有兩種方法可以從熵池中獲取內(nèi)核隨機(jī)數(shù)。一種是通過內(nèi)核導(dǎo)出的隨機(jī)數(shù)接口,另一種是通過特殊的設(shè)備文件/dev/random和/dev/urandom。下面分別討論兩種方法。 熵的輸出接口 1 void get_random_bytes(void *buf, int nbytes) 該函數(shù)返回長度為nbytes字節(jié)的緩沖區(qū)buf,無論熵估計(jì)是否為0都將返回?cái)?shù)據(jù)。使用這個(gè)函數(shù)時(shí)需要在內(nèi)核空間。我們寫一個(gè)小模塊來測試一下。   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #define NUM 10   void get_random_bytes(void *buf, int nbytes);   static int get_random_number(void) {     unsigned long randNum;     int i = 0;       printk(KERN_ALERT "Get some real random number.\n");     for (i=0; i<NUM; i++)     {         get_random_bytes(&randNum, sizeof(unsigned long));         printk(KERN_ALERT "We get random number: %ld\n", randNum);     }     return 0; }   static void random_exit(void) {     printk(KERN_ALERT "quit get_random_num.\n"); }   module_init(get_random_number); module_exit(random_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Test"); Makefile如下:   1 2 3 4 5 6 7 8 9 10 obj-m = get_random_num.o KDIR = $(shell uname -r) PWD = $(shell pwd)   all:     make -C /lib/modules/$(KDIR)/build M=$(PWD) modules clean:     make -C /lib/modules/$(KDIR)/build M=$(PWD) clean   #end# 編譯之后加載模塊,通過dmesg命令輸出系統(tǒng)log最新的信息,可以看到我們的小模塊輸出了10個(gè)從內(nèi)核熵池中得到的隨機(jī)數(shù)。卸載模塊后再次加載可以重新獲取新的隨機(jī)數(shù),觀察輸出結(jié)果,與之前得到的隨機(jī)數(shù)完全不一樣。   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Get some real random number. We get random number: -82199505 We get random number: -276237802 We get random number: 411869317 We get random number: 1779353222 We get random number: 823507551 We get random number: 1061461415 We get random number: 1372137935 We get random number: 1460835009 We get random number: 2002191729 We get random number: -272204344 quit get_random_num. Get some real random number. We get random number: 1111808207 We get random number: -13789055 We get random number: 240443446 We get random number: -606998911 We get random number: 538794850 We get random number: -500786675 We get random number: -1240394927 We get random number: 1233931345 We get random number: 1488497117 We get random number: -177688514 /dev/random & /dev/urandom 這兩個(gè)特殊設(shè)備都是字符型設(shè)備。我們可以在用戶空間通過read系統(tǒng)調(diào)用讀這兩個(gè)設(shè)備文件以此獲取隨機(jī)數(shù)。這兩個(gè)設(shè)備文件的區(qū)別在于:如果內(nèi)核熵池的估計(jì)值為0時(shí), /dev/random將被阻塞,而/dev/urandom不會(huì)有這個(gè)限制。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <assert.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h>   /* 從min和max中返回一個(gè)隨機(jī)值 */   int random_number(int min, int max) {     static int dev_random_fd = -1;     char *next_random_byte;     int bytes_to_read;     unsigned random_value;           assert(max > min);           if (dev_random_fd == -1)     {         dev_random_fd = open("/dev/random", O_RDONLY);         assert(dev_random_fd != -1);     }           next_random_byte = (char *)&random_value;     bytes_to_read = sizeof(random_value);           /* 因?yàn)槭菑?dev/random中讀取,read可能會(huì)被阻塞,一次讀取可能只能得到一個(gè)字節(jié),      * 循環(huán)是為了讓我們讀取足夠的字節(jié)數(shù)來填充random_value.      */     do     {         int bytes_read;         bytes_read = read(dev_random_fd, next_random_byte, bytes_to_read);         bytes_to_read -= bytes_read;         next_random_byte += bytes_read;     }while(bytes_to_read > 0);           return min + (random_value % (max - min + 1)); } 同樣,還可以用dd命令從/dev/urandom中獲取指定字節(jié)數(shù)的隨機(jī)值并寫入文件中保存--如果你需要以文件的形式提供隨機(jī)數(shù)的話。 dd if=/dev/urandom of = file count = 1 bs = bytes   關(guān)于內(nèi)核隨機(jī)數(shù)產(chǎn)生器的詳細(xì)介紹,可參考Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)第二版附錄B。

聲明:免責(zé)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn)自行上傳,本網(wǎng)站不擁有所有權(quán),也不承認(rèn)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,請發(fā)

送郵件至:operations@xinnet.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),本站將立刻刪除涉嫌侵權(quán)內(nèi)容。本站原創(chuàng)內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)

需注明出處:新網(wǎng)idc知識百科

免費(fèi)咨詢獲取折扣

Loading
主站蜘蛛池模板: 又粗又黑又大的吊av | 夜鲁鲁鲁夜夜综合视频 | 久久99精品一区二区蜜桃臀 | 精品久久久久久无码中文字幕 | 天天色综合三 | 日韩免费在线观看视频 | 少妇99| 乱人伦人成品精国产在线 | 国产 日韩 另类 视频一区 | 国产精品刮毛 | 美女又黄又免费的视频 | 成年人视频在线观看免费 | 夜夜草 | 日本精品一二区 | 97超碰导航 | 男女真人后进式猛烈动态图视频 | 国产成人夜色高潮福利app | 大香伊蕉在人线国产最新75 | 久久久久久曰本av免费免费 | 国产国产乱老熟女视频网站97 | √最新版天堂资源网在线下载 | 国产做爰免费观看视频 | h番动漫福利在线观看 | 天天澡夜夜澡人人澡 | 国产成人午夜福利高清在线观看 | 日韩射| 无码一区二区三区爆白浆 | 久久r精品国产99久久6不卡 | 国产一区视频网站 | 9久9久女女热精品视频在线观看 | 亚洲熟妇无码av不卡在线播放 | 一本大道无码人妻精品专区 | 猫咪www免费人成人入口 | 乱子伦国产对白在线播放 | 天天综合网久久综合免费人成 | 亚洲图色av | 少妇天天干 | 亚洲国产人成自精在线尤物 | 国产精品无码专区在线播放 | 黄色一级视频片 | 亚洲美女精品视频 | 国内老熟妇乱子伦视频 | 亚洲精品国产aⅴ成拍色拍 俺去草 | 中文在线www天堂网 真人无码国产作爱免费视频 | 精品无人区麻豆乱码1区2区新区 | 久久久国产99久久国产久灭火器 | 又大又硬又爽18禁免费看 | 日日碰狠狠添天天爽五月婷 | 亚洲成a人片在线观看中文 午夜在线观看视频网站 | 六月婷婷国产精品综合 | 美乳少妇与邻居尤物啪啪 | 日本japanese少妇毛耸耸 | 噼里啪啦完整高清观看视频 | 玖玖在线观看视频 | 欧美极品少妇 | 乱无码伦视频在线观看 | 99久久国产综合精品五月天喷水 | 懂色av噜噜一区二区三区av88 | 久久精品女人 | 一本到无吗专区 | 九九99精品久久久久久综合 | 美女高潮视频在线观看 | 国产精品国产三级国产a | eeuss影院一区二区三区 | 国产精品裸体瑜伽视频 | 久久综合色老色 | 在线免费观看a视频 | 亚洲欧美综合精品另类天天更新 | 狠狠躁夜夜躁人人爽超碰91 | 东京热无码av一区二区 | 黑人猛挺进小莹的体内视频 | 91欧美日韩 | 草女人视频 | 国产乱淫av片免费 | 60老熟女多次高潮露脸视频 | 国产精品av一区二区三区不卡蜜 | 亚洲精品国产成人一区二区 | 尤物网站在线播放 | 黄视频网站在线 | 性免费网站 | 欧美黄色短视频 | 尤物193在线人妻精品免费 | 交做爰xxxⅹ性爽 | 91国偷自产一区二区三区水蜜桃 | 国产一级黄色大片 | 亚州日本乱码一区二区三区 | q2002日韩午夜伦高清 | 夜夜躁狠狠躁日日躁2021日韩 | 草色网 | 欧美爽爽| 日韩综合中文字幕 | 人妻中出受孕 中文字幕在线 | 无码人妻精品一区二区三区99仓本 | 我想看一级黄色片 | 色婷婷综合在线 | 久久精品国内 | 三级毛片在线免费观看 | 欧美~大家屁股网站 | 国产精品自产拍在线18禁 |