Board logo

标题: [数值计算] 批处理中RANDOM生成的是真随机数吗? [打印本页]

作者: fabtb    时间: 2012-8-30 12:20     标题: 批处理中RANDOM生成的是真随机数吗?

本帖最后由 fabtb 于 2012-8-30 12:23 编辑

在批处理中用RANDOM生成的随机数是真随机吗?还是伪随机数?


因为据称批处理RANDOM是靠调用 rand() 函数实现的,而 rand()是伪随机

这篇帖子中讨论这个问题:
http://bbs.bathome.net/thread-10146-1-1.html



所以,用下面这个帖子中二楼写的批处理生成的随机字母数字组合可能被捉到规律,被特别厉害的人破译出来吗?

http://bbs.bathome.net/thread-8149-1-1.html



疑问,请各位高手达人都来研究讨论下。。。。。。。。
作者: 狗屁不通    时间: 2012-8-30 14:29

本帖最后由 狗屁不通 于 2012-8-30 14:39 编辑
  1. @echo off
  2. :reset
  3. if %random% lss 20000 (echo ok&&pause&&goto :reset) else goto :reset
复制代码

  1. @echo off
  2. :reset
  3. if %random% lss 20000 (goto :reset) else (echo ok&&pause&&goto :reset)
复制代码


你试试这俩

但是
  1. @echo off
  2. :reset
  3. if %random% lss 20000 (goto :eof) else (echo ok&&pause&&goto :reset)
复制代码

循环几次就结束了。

random随机数,本人猜测并不是真正的随机数。而且,用脚本和命令行执行效果大不相同的!
作者: fabtb    时间: 2012-8-30 14:39

本帖最后由 fabtb 于 2012-8-30 14:49 编辑

回复 2# 狗屁不通


   前两个运行结果都是一样的,   第三个这里两三次就退出了,怎么回事,汗

  到底什么原理


那下面这个帖子中二楼写的批处理生成的随机字母数字组合可能被捉到规律,被特别厉害的人破译出来吗?

http://bbs.bathome.net/thread-8149-1-1.html

你帮我分析下
作者: fabtb    时间: 2012-8-30 14:41

我弄了两个一样的批处理在指定时间不同电脑上生成随机数,结果并不相同
作者: fabtb    时间: 2012-8-30 14:42

但同一电脑同一时间竟生成了相同的随机数
作者: forfiles    时间: 2012-8-30 15:08

所有语言、脚本生成的都是伪随机数
作者: Demon    时间: 2012-8-30 21:26

既然rand是伪随机数,%random%当然也是伪随机数。
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set /a x = !random!
  4. echo !x!
  5. echo;
  6. call :time t
  7. for /l %%i in (%t%, -1, 0) do (
  8.     set /a y = ((%%i * 214013 + 2531011^) ^>^> 16^) ^& 0x7fff
  9.     if !y! equ !x! (
  10.         echo %%i
  11.         call :srand %%i
  12.         call :rand z
  13.         echo !z!
  14.         echo;
  15.         for /l %%j in (1, 1, 10) do (
  16.             call :rand z
  17.             echo !z! !random!
  18.         )
  19.     )
  20.     echo;
  21.     pause & exit
  22. )
  23. :time
  24. setlocal
  25. for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr .') do set %%x
  26. set /a year = year - 1900, t = (year - 70) * 365 + ((year - 1) ^>^> 2) - 17, leap = year ^& 3
  27. for /f "tokens=%month%" %%i in ("-1 30 58 89 119 150 180 211 242 272 303 333 364") do set /a t += %%i
  28. if %leap% equ 0 if %month% gtr 1 set /a t += 1
  29. set /a t += day, t *= 24, t += hour, t *= 60, t += minute, t *= 60, t += second
  30. endlocal & set %1=%t%
  31. goto :eof
  32. :srand
  33. set /a _holdrand = %1
  34. goto :eof
  35. :rand
  36. set /a _holdrand = _holdrand * 214013 + 2531011
  37. set /a %1 = (_holdrand ^>^> 16) ^& 0x7fff
  38. goto :eof
复制代码

作者: plp626    时间: 2012-8-30 23:26

回复 7# Demon


    核心的那两行如何得到的, 214013 ,2531011这两个常数?
-------------------
友情提示:获取时间的部分可以很精简的;
作者: plp626    时间: 2012-8-30 23:37

原来老帖就有了这俩常数:
http://bbs.bathome.net/thread-10146-1-1.html
  1. 下面我们到msvcrt.dll里看看这个rand函数到底做了什么. 下面这个就是rand函数
  2. msvcrt&rand()函数  ;以下就是msvcrt&rand函数,简化下给大家看
  3. push 1
  4. call FlsGetValue  ;返回值eax 是一个结构的指针(这个结构与纤程有关,我们不管其具体含义)
  5. mov ecx,[eax + 14h]  ;[eax + 14h]对我们的随机数 至关重要 !从计算过程可以看出,它直接影响随机数的计算!
  6. imul ecx,ecx,343FDh  ;ecx里就是从[eax + 14h]取出来的值,看它在计算了
  7. add ecx,269EC3h
  8. mov [eax + 14h],ecx  ;这里更新了 [eax + 14h],这样下次我们再取随机数,再用到[eax + 14h],那么他已经不是原来的值了
  9. mov eax,ecx   ;这样每一次的数值才可能不同
  10. shr eax,10h
  11. and eax,7FFFh  ;与运算保证了随机数的范围0~32767。此时的eax中的值就是 我们最后 得到的%random%的值
复制代码

作者: garyng    时间: 2012-8-31 01:17

弱弱问下,伪随机数是什么?
作者: Demon    时间: 2012-8-31 07:58

回复  Demon


    核心的那两行如何得到的, 214013 ,2531011这两个常数?
-------------------
友 ...
plp626 发表于 2012-8-30 23:26


请指点。
作者: CrLf    时间: 2012-8-31 11:33

本帖最后由 CrLf 于 2012-8-31 11:36 编辑

回复 11# Demon


    日期算法:http://bbs.bathome.net/viewthread.php?tid=16147
作者: fabtb    时间: 2012-8-31 12:06

本帖最后由 fabtb 于 2012-8-31 12:07 编辑

。。。。

那用下面这个帖子中二楼写的批处理生成的随机字母数字组合做密码可能被捉到规律,被特别厉害的人破译出来吗?

http://bbs.bathome.net/thread-8149-1-1.html
作者: Demon    时间: 2012-8-31 20:19

回复  Demon


    日期算法:
CrLf 发表于 2012-8-31 11:33
  1. @echo off
  2. call :time t
  3. echo %t%
  4. pause & exit
  5. :time
  6. setlocal
  7. for /f "skip=1 tokens=1-9" %%a in ('wmic path win32_utctime ^| findstr .') do set /a m=%%e+9,m%%=12,y=%%i-m/10,t=365*y+y/4-y/100+y/400+(m*306+5)/10+%%a-719469,t=t*86400+%%c*3600+%%d*60+%%g
  8. endlocal & set %1=%t% & goto :eof
复制代码
这种Write Only的代码是反人类的。
作者: CrLf    时间: 2012-8-31 20:35

回复 14# Demon


    反人类…笑尿了,不过好的算法经常不合常规思路哈,难免降低可读性




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2