当前位置: 代码网 > it编程>编程语言>Asp.net > c#中生成随机数的五种方法

c#中生成随机数的五种方法

2025年07月27日 Asp.net 我要评论
在 c# 中,生成随机数有多种方式,适用于不同场景。以下是5种主要方法及其对比:计算机中不存在真正的 "随机数",我们生成的随机数本质是伪随机数—— 通过特

在 c# 中,生成随机数有多种方式,适用于不同场景。以下是5种主要方法及其对比:

计算机中不存在真正的 "随机数",我们生成的随机数本质是伪随机数—— 通过特定算法和初始条件(种子)计算出的序列。这些序列看似无序,但在相同种子下会完全重复,因此也被称为 "假随机"。

典型使用场景: 注册账号的验证码、唯一标识符生成、随机点名器、抽奖系统、游戏中的随机事件等。

1. 使用random类(基础随机数)

特点:基于种子的伪随机数生成器,性能较高,适合普通随机场景。

示例代码

// 创建 random 实例(默认使用时间戳作为种子)
random random = new random();
​
// 生成整数:[minvalue, maxvalue)
int randomint = random.next(1, 101);  // 生成 1 到 100 之间的随机整数
​
// 生成浮点数:[0.0, 1.0)
double randomdouble = random.nextdouble();  // 生成 0.0 到 1.0 之间的随机小数

注意事项

种子问题:短时间内创建多个random实例可能生成相同序列(因时间种子相同)。

// 错误示例:每次循环创建新实例,可能生成相同随机数
for (int i = 0; i < 5; i++) {
    console.writeline(new random().next(100)); // 可能输出重复值
}

解决方案:复用单个 random 实例。

生成随机字符: 利用 ascii 码范围生成 a-z 的随机字符串(97-122 对应小写字母):

random random5 = new random();
string result = "";
for (int i = 0; i < 4; i++)
{
    char c = (char)random5.next(97, 123); // 生成97-122的随机数,转换为字符
    result += c;
}
console.writeline(result); // 例如:"kqzx"

2. 使用system.random.shared(线程安全版本)

特点:.net 6+ 引入的静态线程安全随机数生成器,无需手动同步。

示例代码

// 生成线程安全的随机数
int saferandomint = random.shared.next(1, 101);  // 线程安全的整数
double saferandomdouble = random.shared.nextdouble();  // 线程安全的小数

优势

  • 无需担心多线程竞争问题,性能优于手动加锁的 random
  • 适用于多线程环境(如并行计算)。

3. 使用system.security.cryptography.randomnumbergenerator(加密安全随机数)

特点:使用操作系统的加密随机数生成器,生成高质量随机数,适用于安全敏感场景(如密码、令牌生成)。

using system.security.cryptography;
​
// 生成加密安全的随机整数
byte[] buffer = new byte[4];  // 4字节 = 32位整数
using (randomnumbergenerator rng = randomnumbergenerator.create()) {
    rng.getbytes(buffer);  // 填充随机字节
    int securerandomint = bitconverter.toint32(buffer, 0);
    console.writeline(math.abs(securerandomint % 100));  // 转换为 0-99 的整数
}
​
// 更简便的写法(.net 6+)
int secureint = randomnumbergenerator.getint32(1, 101);  // 直接生成 1-100 的整数

适用场景

  • 密码学相关场景(如生成加密密钥)。
  • 安全令牌、验证码生成。

4. guid(全球唯一标识符)

guid(globally unique identifier)是 128 位的唯一标识符,通过系统时间、硬件 id 等多维度信息计算生成,重复概率极低(可视为全球唯一)。

核心特点:

  • 格式:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx(32 位十六进制数,含连字符),例如:6f9619ff-8b86-d011-b42d-00c04fc964ff
  • 生成方式:直接调用guid.newguid()静态方法。
适用场景:

生成产品密钥、订单号、数据库主键、分布式系统中的唯一标识等。

console.writeline(guid.newguid()); 
// 输出示例:a27fc3ff-f785-4522-bced-7c0f24f0d0e8

5.rngcryptoserviceprovider(加密级随机数)

属于加密安全的随机数生成器,基于操作系统底层的加密算法,生成高质量随机数,适用于安全性要求极高的场景。

核心用法:

通过字节数组接收随机数据,可转换为字符串或数值使用:

// 创建加密随机数生成器实例
using (rngcryptoserviceprovider rcsp = new rngcryptoserviceprovider())
{
    byte[] bytes = new byte[10]; // 指定随机数长度(10字节)
    rcsp.getbytes(bytes); // 生成随机字节并填充到数组
    console.writeline(bitconverter.tostring(bytes)); 
    // 输出示例:3a-7b-2d-...(十六进制格式,以连字符分隔)
}

特点:

  • 随机性强:基于硬件或系统环境的熵值(不可预测性更高)。
  • 线程安全:支持多线程环境。
  • 性能较低:因加密算法复杂,生成速度慢于random

适用场景:

密码加密、令牌生成、敏感数据加密密钥等安全敏感场景。

方法对比

方法性能线程安全随机性质量适用场景
random普通(伪随机)游戏、随机排序、普通模拟
system.random.shared普通(伪随机)多线程环境下的普通随机需求
randomnumbergenerator加密安全(真随机)密码学、安全令牌、敏感数据
guid极高(近乎唯一)唯一标识(订单号、主键等)
rngcryptoserviceprovider极高(加密级)安全场景(密码、密钥等)

总结

  • 普通场景:使用 random 并复用实例。
  • 多线程场景:使用 system.random.shared
  • 安全敏感场景:使用 randomnumbergenerator

补充说明

  1. random的扩展用法: 生成随机字符除了通过 ascii 码(97-122 对应 a-z),还可直接从字符集抽取:

    string chars = "qwertyuiopasdfghjklzxcvbnm";
    random ran = new random();
    string res = "";
    for (int i = 0; i < 4; i++)
    {
        res += chars[ran.next(chars.length)]; // 从字符集中随机取字符
    }

    洗牌算法:

  2. guid的唯一性: guid 的唯一性基于 "概率极低",理论上存在重复可能,但实际应用中可视为绝对唯一,无需担心冲突。

  3. .net core/.net 5 + 的新选择: 对于加密随机数,推荐使用randomnumbergenerator(.net 6+)替代rngcryptoserviceprovider(已过时),用法更简洁。

    // .net 6+ 推荐写法
    byte[] bytes = new byte[10];
    randomnumbergenerator.fill(bytes); // 填充随机字节

到此这篇关于c#中生成随机数的三种方法的文章就介绍到这了,更多相关c# 生成随机数内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com