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

相关推荐
z落落4 小时前
C#参数区别
java·算法·c#
雪豹阿伟5 小时前
11.C# —— 数组属性、高级方法与 Lambda 表达式
c#·上位机
无限进步_5 小时前
【C++】weak_ptr、循环引用与线程安全
开发语言·数据结构·c++·算法·安全
菜菜的顾清寒5 小时前
力扣hot100(37)栈-有效的括号
java·开发语言
Circ.6 小时前
Java 远程调用 NX 11 完整实战:参数读取、修改、STP 文件导出(附环境配置 + 源码)
java·开发语言·nx11
唐青枫6 小时前
C#.NET YARP 服务发现实战:接入 Consul 和 Kubernetes 动态发现后端服务
c#·.net
2401_833269306 小时前
【无标题】
java·开发语言
宇宙realman_9996 小时前
420B污染度等级查询代码
java·开发语言·算法
小白学大数据6 小时前
Playwright 爬虫:Python 爬取 JS 渲染的 JSP 网站
开发语言·javascript·爬虫·python·数据分析