zoukankan      html  css  js  c++  java
  • 【转】亂數產生器:Random 與 RNGCryptoServiceProvider

    一般眾所周知的亂數的產生應該都會使用 Random 類別,而在大部分的情境中使用 Random 類別其實是足夠用的,例如說你想要透過亂數選取目錄中的照片輸出到網頁中,或是將篩選出來的資料亂數排序後輸出到檔案(例如說抽獎程式)。

    假設你要用 Random 類別產生 10 組最大值為 100 的亂數(0 ~ 100),可以用以下寫法:

    Random rnd = new Random();
    for (int i = 0; i < 10; i++)
    {
       int randomNumber = rnd.Next(100);
    }

    詳細的說明與範例可參照 MSDN 文件:Random 類別。

    不過 Random 類別是使用「有限性數學演算法」所計算出來的結果(目前 Random 類別的實作是以 Donald E. Knuth 的減法亂數產生器演算法為主),因此計算出來的「亂數」其實不是真的那麼亂,若要將亂數套用在「密碼產生器」或用來產生「強勢金鑰(Strong Key)」的話,就應該使用System.Security.Cryptography.RNGCryptoServiceProvider 類別幫你產生「夠強」的亂數。

    如果要使用 RNGCryptoServiceProvider 類別產生亂數的話可以參考 MSDN 上的範例,或是用我之前常用的一個靜態類別來產生亂數(介面跟 Random 類別類似),如下:

    using System;
    using System.Security.Cryptography;
    
    /// <summary>
    /// 使用 RNGCryptoServiceProvider 產生由密碼編譯服務供應者 (CSP) 提供的亂數產生器。
    /// </summary>
    public static class RNG
    {
        private static RNGCryptoServiceProvider rngp = new RNGCryptoServiceProvider();
        private static byte[] rb = new byte[4];
    
        /// <summary>
        /// 產生一個非負數的亂數
        /// </summary>
        public static int Next()
        {
            rngp.GetBytes(rb);
            int value = BitConverter.ToInt32(rb, 0);
            if (value < 0) value = -value;
            return value;
        }
        /// <summary>
        /// 產生一個非負數且最大值 max 以下的亂數
        /// </summary>
        /// <param name="max">最大值</param>
        public static int Next(int max)
        {
            rngp.GetBytes(rb);
            int value = BitConverter.ToInt32(rb, 0);
            value = value % (max + 1);
            if (value < 0) value = -value;
            return value;
        }
        /// <summary>
        /// 產生一個非負數且最小值在 min 以上最大值在 max 以下的亂數
        /// </summary>
        /// <param name="min">最小值</param>
        /// <param name="max">最大值</param>
        public static int Next(int min, int max)
        {
            int value = Next(max - min) + min;
            return value;
        }
    }

    有個這個「夠強」的亂數產生器,就可以用來產生密碼了,如果你要產生一組固定長度 8 碼的密碼,可以用以下程式碼:

    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    char[] chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
    int length = RNG.Next(8, 8);
    for (int i = 0; i < length; i++)
    {
        sb.Append(chars[RNG.Next(chars.Length - 1)]);
    }
    string YourPassword = sb.ToString();

    這樣的密碼並沒有說就比較安全,只能說在演算法的角度來看是比較亂的密碼。如果你只是想要一串「亂亂的文字」的話,我也看過有人直接用 Guid 來當作亂碼。

    string RandomString = Guid.NewGuid().ToString();

    下面這個是我實做 RNGCryptoServiceProvider 的密碼產生器:

    實做 RNGCryptoServiceProvider 的密碼產生器產生的密碼:[67ed3voueE]

    相關連結

  • 相关阅读:
    RocketMQ logback使用实践
    用SLF4j/Logback打印日志-3
    UI调试工具 SAK 布局 [MD]
    Gradle 翻译 Merge AndroidManifest 合并清单文件 [MD]
    Gradle 翻译 build dependencies 依赖 [MD]
    Gradle 翻译 tips and recipes 使用技巧 [MD]
    依赖注入 DI 控制反转 IOC 概念 案例 [MD]
    属性动画 基本使用案例 [MD]
    架构 MVC MVP MVVM 简介 [MD]
    MMKV 多进程K-V组件 SP [MD]
  • 原文地址:https://www.cnblogs.com/sofire/p/1754441.html
Copyright © 2011-2022 走看看