C# 实现一个基于线程的随机数工具类

文章介绍了如何在C#中通过使用系统启动时间戳和线程局部变量改进Random类生成随机数的质量,以降低重复值概率,并提及了System.Security.Cryptography命名空间和WindowsAPI中的高级随机数生成选项。

写在前面

由于C#中生成随机数使用的算法是线性同余法,意味着得出的是伪随机数,直接调用Random类来生成,出现重复数值的概率非常高。

Random random = new Random();
var rnd = random.Next();

这个结果肯定是不满足要求的,可以采用系统启动时间戳来做随机数种子,同时结合线程变量来生成随机数,这样得到的随机数更为可靠。

代码实现

   public static class RandomProvider
    {
        private static int _seed = Environment.TickCount;

        private static ThreadLocal<Random> randomWrapper = new ThreadLocal<Random>(() =>
            new Random(Interlocked.Increment(ref _seed))
        );

        public static Random GetThreadRandom()
        {
            _seed = Environment.TickCount;
            return randomWrapper.Value;
        }

        public static int GetRandomValue(int min, int max)
        {
            var random = GetThreadRandom();
            return random.Next(min, max + 1);
        }
        public static float GetRandomValue(float min, float max)
        {
            var random = GetThreadRandom();
            var minFloat = (int)(min * 1000);
            var maxFloat = (int)(max * 1000);
            return random.Next(minFloat, maxFloat + 1) / 1000;
        }

        public static int Range(int min, int max)
        {
            return GetRandomValue(min, max);
        }

        public static float Range(float min, float max)
        {
            return GetRandomValue(min, max);
        }

        public static string GetRandomName(int length)
        {
            var wArr = new string[] 
            {
                "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
                "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
            };

            var nArr = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            var sList = new List<string>();
            for (int j = 0; j < length; j++)
            {
                var str = string.Empty;
                if (j > 0 && j < length - 1)
                {
                    var n = GetRandomValue(0, 100);
                    if (n < 20)
                    {
                        var x = GetRandomValue(0, 9);
                        str = nArr[x];
                        sList.Add(str);
                        continue;
                    }
                }

                var i = GetRandomValue(0, 51);
                str = wArr[i];
                sList.Add(str);
            }

            return string.Join(string.Empty, sList);
        }
    }

总结

为了生成更加可靠的随机数,还有很多其他的方式,比如微软在System.Security.Cryptography命名空间下,就提供一个名为RNGCryptoServiceProvider的类,它采用系统当前的硬件信息、进程信息、线程信息、系统启动时间和当前精确时间作为填充因子,通过更好的算法生成高质量的随机数。在Windows Api中也提供了一个非托管的随机数生成函数CryptGenRandom,由于是C++实现的,在C#中调用需要另外加一层封装;在大部分情况下本文所提供的随机数生成类产生的随机数质量已经可以满足需求了。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值