C#随机数

一、随机数核心原理

1. 伪随机数概念

计算机中没有真正的随机数。

代码生成的随机数都是伪随机(假随机):

通过固定算法 + 初始种子 → 计算出一串固定数字序列,我们只是依次从队列中取出数字

2. 种子规则(核心)

C#会自动使用当前系统的时间作为种子

  • 种子相同 → 随机数序列完全相同

  • 种子不同 → 随机数序列不同

  • 不手动指定种子:默认以当前系统时间作为种子

3. 使用场景

账号注册、唯一ID、随机点名、抽奖、验证码、秘钥生成等


二、Random 普通随机数(最常用)

1. 固定种子(随机数可复现)

手动指定种子,种子一致,随机数序列完全一致。

复制代码
// 指定种子为10
Random rnd = new Random(10);
Console.WriteLine(rnd.Next()); 

// 两个对象种子相同,生成的随机数完全一致
Random rnd2 = new Random(100);
Random rnd3 = new Random(100);
Console.WriteLine(rnd2.Next() + ":" + rnd3.Next());
Console.WriteLine(rnd2.Next() + ":" + rnd3.Next());

2. 默认种子(时间种子,真正随机)

不写种子,默认使用系统时间作为种子,时间一直在变,所以随机数不同。

复制代码
Random rnd4 = new Random();

// Next(最小值,最大值)  包含最小值,不包含最大值
Console.WriteLine(rnd4.Next(10, 21)); // 10~20

// Next(最大值)  默认从0开始,不包含最大值
Console.WriteLine(rnd4.Next(21)); // 0~20

3. 高频大坑:循环内new Random()

绝对不要在for循环里面new Random对象!

原因:循环执行速度极快,毫秒时间一致 → 种子一致 → 每次随机数一模一样。

复制代码
// 正确写法:对象只创建一次
Random rnd5 = new Random();
for (int i = 0; i < 4; i++)
{
    Console.WriteLine(rnd5.Next());
}

// 错误写法!!!
//for (int i = 0; i < 4; i++)
//{
//    Random rndErr = new Random(); 
//    Console.WriteLine(rndErr.Next());
//}

三、实战:随机生成字符 / 验证码

方式1:通过字符串下标随机取值

cs 复制代码
// 小写字母库
string s = "qwertyuiopasdfghjklzxcvbnm";
Random rnd6 = new Random();

// 随机取出一个字符
int num1 = rnd6.Next(s.Length); 
Console.WriteLine(s[num1]);

// 生成4位随机字符验证码
Random rnd7 = new Random();
string res = "";
for (int i = 0; i < 4; i++)
{
    res += s[rnd7.Next(s.Length)];
}
Console.WriteLine(res);

方式2:通过ASCII码生成字母(专业写法)

小写字母 a-z ASCII范围:97 ~ 122

Next(97,123) 包含97,不包含123,刚好覆盖所有小写字母

cs 复制代码
Random rnd8 = new Random();
string res1 = "";
for (int i = 0; i < 4; i++)
{
    // 数字强转为char字符
    res1 += (char)rnd8.Next(97, 123);
}
Console.WriteLine(res1);

四、GUID 全局唯一标识符(真正唯一)

1. 概念

GUID(Globally Unique Identifier)全球唯一标识符。

根据:系统时间 + 硬件ID + 算法 生成128位唯一值,几乎不会重复。

2. 格式

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

由 0-9、a-f 组成的32位十六进制数

3. 使用场景

订单号、产品秘钥、文件唯一ID、数据库唯一标识

4. 代码使用

cs 复制代码
Console.WriteLine(Guid.NewGuid());
// 示例结果:f4ea33ed-8e52-462e-8d3a-620e38f3f91b

五、RNGCryptoServiceProvider 加密级随机数(安全随机)

1. 特点

Random是伪随机(可预测),安全性低;

RNGCryptoServiceProvider 是加密级随机数,不可预测,用于密码、秘钥等高安全场景。

cs 复制代码
// 创建加密随机对象
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

// 创建长度为10的字节数组容器
byte[] bs = new byte[10];

// 填充随机字节数据
rng.GetBytes(bs);

// 字节数组转字符串输出
Console.WriteLine(BitConverter.ToString(bs));

六、三种随机方式对比总结(必背)

随机方式 随机性 安全性 使用场景
Random 伪随机,种子可控 低,可预测 抽奖、点名、普通验证码
GUID 全局唯一 极高 订单ID、唯一标识、秘钥
RNGCryptoServiceProvider 加密真随机 最高,不可预测 密码加密、安全令牌、付费秘钥

七、终极易错点总结

  • Random对象绝对不能写在循环内部,否则随机数全部重复

  • 种子相同 → 随机数序列一定相同

  • Next(最小值,最大值):含左不含右

  • 普通Random不安全,密码相关必须用加密随机或GUID

相关推荐
http阿拉丁神猫3 小时前
Go语言入门笔记:从基础到开发环境搭建(二)
开发语言·笔记·golang
不会就选b4 小时前
C++补充部分(一)--lambda 表达式
开发语言·c++
czhc11400756634 小时前
同值短路与单一真值源:属性不是命令,状态只有一个家
c#
Pniubi7 小时前
HashMap的扩容和树化边界
java·开发语言
gCode Teacher 格码致知9 小时前
Pandas教学-17:Series与Dataframe的关系
开发语言·python·pandas
发量惊人的中年网工9 小时前
分公司访问总部ERP慢怎么办?SD-WAN组网的排查与验收要点
服务器·开发语言·php
下页、再停留9 小时前
【C#桌面客户端系列学习-15】生成可视化图表之折线图、柱状图、饼状图
开发语言·c#
ShineWinsu9 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
益莱储中国11 小时前
深度解析:RF 实验室从 5G迈向 6G 的过程中保持技术领先与设备升级的路径
开发语言·php
benchmark_cc12 小时前
Python 量化系统如何设计统一的数据访问接口:从策略解耦到数据层架构
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash