标题:分享一個比官方快10倍的隨機數算法, 經過測試, 一次性可產生40億個不同的隨 ...
只看楼主
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
结帖率:100%
 问题点数:0 回复次数:9 
分享一個比官方快10倍的隨機數算法, 經過測試, 一次性可產生40億個不同的隨機數

程序代码:

#include <stdio.h>
#include <stdlib.h>


int rand2(int min, int max)
{
    static unsigned long long z = 1, d = 0, s = 0, i = 256;
    static unsigned char* zz = (unsigned char*)&z, * dd = (unsigned char*)&d, *ss = (unsigned char*)&s;
    if ((++i) >= 256) { if (d) free((void*)d); d = (unsigned long long)malloc(8); i = 0; }        // 產生隨機堆位址到d
    z = z * 17 + 139;        // 線性求餘法產生0~256之間的隨機數到z
    ss[0] = zz[0] + dd[0] + dd[7] + ss[3];        // 隨機數和堆位址混合到ss
    ss[1] = zz[1] + dd[1] + dd[6] + ss[0];
    ss[2] = zz[2] + dd[2] + dd[5] + ss[1];
    ss[3] = zz[3] + dd[3] + dd[4] + ss[2];
    return (int)(s % ((long long)max - min) + min);
}


int main()
{
    int max = 100;
    do for (int i = 0; i < max; i++) printf(i % 10 == 0 ? "\n%d\t" : "%d\t", rand2(0, max));
    while (printf("\n\n按回車鍵繼續:"), getchar() == '\n');
    return 0;
}


搜索更多相关主题的帖子: char int max long unsigned 
2021-11-28 19:06
diycai
Rank: 8Rank: 8
等 级:贵宾
威 望:19
帖 子:147
专家分:895
注 册:2021-5-18
得分:0 
线性同余法的伪随机数,Backward secrecy和Forward secrecy安全性为零,曾经有某银行用这个随机数做抽奖游戏,被人薅了羊毛几千万羊毛。
2021-11-28 19:36
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
得分:0 
回复 2楼 diycai
看清楚代碼, 混合了隨機堆位址, 再加上隨機數重新計算, 反正我看不出哪裡可以破解的方法, 即使是數學天才
2021-11-29 00:32
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
得分:0 
回复 2楼 diycai
確切來說這個不是線性同餘法隨機數, 而是我重新研發的新的隨機數算法
2021-11-29 00:41
diycai
Rank: 8Rank: 8
等 级:贵宾
威 望:19
帖 子:147
专家分:895
注 册:2021-5-18
得分:0 
回复 4楼 我善治鬼
去掉线性同余,看看还剩下什么。
2021-11-29 11:43
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
得分:0 
回复 5楼 diycai
你在搞笑嗎, 即使我去掉這個線性同餘依然每次出現的是不同隨機隨, 這個已經是新的隨機數算法了, 可以命名了

2021-11-29 12:51
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
得分:0 
回复 5楼 diycai
唯一要改動一下的是這裡
return (int)((unsigned long)s % (max - min) + min);
我給出這個是4字節版本
實際上我使用的是8節字節版本, 沒有進行轉換類型

2021-11-29 13:05
diycai
Rank: 8Rank: 8
等 级:贵宾
威 望:19
帖 子:147
专家分:895
注 册:2021-5-18
得分:0 
回复 7楼 我善治鬼
堆分配和堆释放太依赖 库算法了, 有链表形式也有固定块形式, 记录了未分配的空间段或块列表, 有的查找最长的未分配空间来分配,有的查找最合适的未分配空间来分配,先释放再分配,在单进程或单线程里,很大可能就是同一地址。
你可以试试
程序代码:
#include <stdio.h>
#include <stdlib.h>


int rand2(int min, int max)
{
    static unsigned long long z = 1, d = 0, s = 0, i = 256;
    static unsigned char* zz = (unsigned char*)&z, * dd = (unsigned char*)&d, *ss = (unsigned char*)&s;
    if ((++i) >= 256) { if (d) free((void*)d); d = (unsigned long long)malloc(8); i = 0; }        // 產生隨機堆位址到d
    printf("%lld\n", d);
    z = z * 17 + 139;        // 線性求餘法產生0~256之間的隨機數到z
    ss[0] = zz[0] + dd[0] + dd[7] + ss[3];        // 隨機數和堆位址混合到ss
    ss[1] = zz[1] + dd[1] + dd[6] + ss[0];
    ss[2] = zz[2] + dd[2] + dd[5] + ss[1];
    ss[3] = zz[3] + dd[3] + dd[4] + ss[2];
    return (int)(s % ((long long)max - min) + min);
}


int main()
{
    int max = 100;
    do for (int i = 0; i < max; i++) rand2(0, max);
    while (printf("\n\n按回車鍵繼續:"), getchar() == '\n');
    return 0;
}


另外线性同余算法由于结果的低几位无法满足随机性要求,都是需要舍弃的,比如最低为必定为0 1 0 1 0 1的循环。
2021-11-29 14:17
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
得分:0 
回复 8楼 diycai
有道理, 其實可以只在函數第一次調用時只初始化一次靜態隨機位址, 反正隨機數是混亂不可計算的, 也推算不出來, 沒有必要每256次重新分配一次位址, 性能又有質的提升
我剛測試過, 在產生1億個隨機數的時候依然正常可以產生70%不同的隨機數
2021-11-29 15:58
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
得分:0 


這是我的測試, 無論有多少數位都可以產生70%不同的隨機數位
我最多只敢測試1億個, 太多了計算機內存不夠吃不消, 跑不動
2021-11-29 16:32



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-507679-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.208402 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved