.net.Frameword中提供了一個(gè)專門產(chǎn)生隨機(jī)數(shù)的類System.Random,此類默認(rèn)情況下已被導(dǎo)入,編程過程中可以直接使用。我們知道,計(jì)算機(jī)并不能產(chǎn)生完全隨機(jī)的數(shù)字,它生成的數(shù)字被稱為偽隨機(jī)數(shù),它是以相同的概率從一組有限的數(shù)字中選取的,所選的數(shù)字并不具有完全的隨機(jī)性,但就實(shí)用而言,其隨機(jī)程度已經(jīng)足夠了。
是一個(gè)很常用的方法,但是一直沒有注意到該方法的第二個(gè)參數(shù)(最大值),這個(gè)參數(shù)并不在隨機(jī)數(shù)取值范圍內(nèi)。
簡(jiǎn)單舉例:int theNum = ran.Next(1, 4); //theNum的取值范圍是1~3,并不包括4. 一定要注意這個(gè),今天要不是需要一個(gè)范圍小的隨機(jī)數(shù),恐怕我一直都會(huì)犯這個(gè)錯(cuò),一直以為這樣是生成1~4的隨機(jī)數(shù)呢。
下面內(nèi)容摘自MSDN,原文:https://msdn.microsoft.com/zh-cn/library/2dx6wyd4(v=vs.110).aspx
Random.Next 方法 (Int32, Int32)
public virtual int Next( int minValue, int maxValue )
參數(shù)
minValue
類型:System.Int32
返回的隨機(jī)數(shù)的下界(隨機(jī)數(shù)可取該下界值)。
maxValue
類型:System.Int32
返回的隨機(jī)數(shù)的上限(隨機(jī)數(shù)不能取該上限值)。 maxValue 必須大于等于 minValue。
返回值
類型:System.Int32
大于等于 minValue 且小于 maxValue 的 32 位帶符號(hào)整數(shù),即:返回值的范圍包括 minValue 但不包括maxValue。如果 minValue 等于 maxValue,則返回 minValue。
Random類是一個(gè)產(chǎn)生偽隨機(jī)數(shù)字的類,它的構(gòu)造函數(shù)有兩種,一個(gè)是直接New Random(),另外一個(gè)是New Random(Int32),前者是根據(jù)觸發(fā)那刻的系統(tǒng)時(shí)間做為種子,來產(chǎn)生一個(gè)隨機(jī)數(shù)字,后者可以自己設(shè)定觸發(fā)的種子,一般都是用UnCheck((Int)DateTime.Now.Ticks)做為參數(shù)種子,因此如果計(jì)算機(jī)運(yùn)行速度很快,如果觸發(fā)Randm函數(shù)間隔時(shí)間很短,就有可能造成產(chǎn)生一樣的隨機(jī)數(shù),因?yàn)閭坞S機(jī)的數(shù)字,在Random的內(nèi)部產(chǎn)生機(jī)制中還是有一定規(guī)律的,并非是真正意義上的完全隨機(jī)。
Random類產(chǎn)生隨機(jī)數(shù)字的主要辦法是Next(),Next(100)產(chǎn)生一個(gè)比100小的正整數(shù),Next(1,100)在1到100中間產(chǎn)生一個(gè)隨機(jī)數(shù)字,而利用Ticks(以100毫秒做基礎(chǔ)單位的時(shí)間數(shù)量單位)來產(chǎn)生隨機(jī)數(shù),還是存在合理性的。
/// <summary> /// 用隨機(jī)數(shù)實(shí)現(xiàn)一件事情出現(xiàn)的概率是10%,另一件事情出現(xiàn)的概率是90% /// </summary> /// <param name="args"></param> private static void Main(string[] args) { //string[] arr = { "10", "90", "90", "90", "90", "90", "90", "90", "90", "90" }; Random ran = new Random(unchecked((int)DateTime.Now.Ticks)); int num1 = 0; int num2 = 0; for (int i = 0; i < 100000; i++) { int n = ran.Next(0, 10); //string str = arr[n]; if (n == 0) { num1++; } else { num2++; } } Console.Write(num1 + "--" + num2); } /// <summary> ///舉例:用等差概率取0-99的整數(shù),但讓99的出現(xiàn)幾率最大,98比99小一點(diǎn),97比98小一點(diǎn),0出現(xiàn)的幾率最小 /// </summary> /// <param name="number"></param> /// <returns></returns> private static int GetRandom(int number) { int maxNumber = number + 1; int maxRange = ((1 + maxNumber) * maxNumber) / 2; Random rd = new Random(); int randomNumber = Math.Abs(rd.Next() % maxRange); int sum = 0; for (int i = 0; i < maxNumber; i++) { sum += (maxNumber - i); if (sum > randomNumber) { return i; } } return -1; }
昨天網(wǎng)站被人DOS攻擊,網(wǎng)站的同時(shí)連接數(shù)達(dá)到了1000多,我的程序是一個(gè)投票的程序,在投票之前需要做驗(yàn)證碼認(rèn)證,不過驗(yàn)證碼是放在Cookie中的,這給了作弊者一個(gè)可乘之機(jī)。在作弊者發(fā)動(dòng)大規(guī)模作弊攻擊時(shí),網(wǎng)站的驗(yàn)證碼出現(xiàn)了很奇怪的現(xiàn)象,總是返回AAAA,也就是說Random.Next(int number)方法總是返回0了。這是怎么回事呢?
通過google查出Random確有這個(gè)毛病,原因是Random本身是非線程安全的,而在Asp.net中是多線程環(huán)境,Random.Next方法在多線程環(huán)境下跑到一定時(shí)候,就會(huì)出現(xiàn)這種情況。
他推薦使用RandomNumberGenerator類,我當(dāng)時(shí)情急之中,直接使用了Guid.NewGuid().ToString(0,4)了?;蛘咄ㄟ^下面的類,編程線程安全的調(diào)用Random類的Next方法。
class ThreadSafeRandom { private static Random random = new Random(); public static int Next() { lock (random) { return random.Next(); } } }
如對(duì)本文有疑問,請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答??! 點(diǎn)擊進(jìn)入論壇