在C#中生成随机十六进制数

38

我该如何使用C#生成指定长度的随机十六进制数?

9个回答

62
static Random random = new Random();
public static string GetRandomHexNumber(int digits)
{
    byte[] buffer = new byte[digits / 2];
    random.NextBytes(buffer);
    string result = String.Concat(buffer.Select(x => x.ToString("X2")).ToArray());
    if (digits % 2 == 0)
        return result;
    return result + random.Next(16).ToString("X");
}

23
Random random = new Random();
int num = random.Next();
string hexString = num.ToString("X");

random.Next()接受参数来指定最小值和最大值,因此这就是你控制长度的方式。


1
只有当 length <= 8 时才能正常工作,因为 int.MaxValue 可以用 8 个十六进制数字表示。 - Mehrdad Afshari
如果他真的想要十六进制字符串的长度由他自己选择,你需要编写代码来计算最小长度为“x”和最大长度为“x”的十六进制数。 - colithium
是的。我故意省略了那个,但你基本上只需要对0xF?(请原谅我的正则表达式)进行转换,以找到与所需长度匹配的任何整数。 - womp
int num = random.Next(1000, 5000); - 在这里你可以设置任何范围的数字 random.Next(1000, 5000);,这将生成1000到5000之间的随机数。 - Andrei Krasutski

9

取决于你需要多么随机,但这里有三个选择:

  1. 我通常只使用Guid.NewGuid并选择其中的一部分(取决于我需要多大的数字)。

  2. 如果你只是想要“足够随机”,System.Random(参见其他答复)是不错的选择。

  3. System.Security.Cryptography.RNGCryptoServiceProvider


2
将GUID切片似乎对我来说是一个真正糟糕的想法。它们只有作为一个整体才是唯一的。许多GUID的位肯定不符合随机要求。 - spender
1
@spender 是正确的,例如许多 GUID 包含生成它们的个人电脑的 MAC 地址。 - Eric Haskins
1
哦,不是的,基于 MAC 地址的 GUID 已经在大约 2000 年退役了,因为它们被认为存在潜在的安全问题。现在,GUID 是由随机数生成器(122 位随机数,6 位非随机数)生成的。无论如何,使用 GUID 的 32(或更多)位切片比 System.Random 给出一个更随机的数字。也就是说 - 除非您调用 UuidCreateSequential,这是为了向后兼容而添加的,以防有人想要旧款式的 GUID,但那是另一回事了。 - KristoferA
3
好的,System.Random 的文档可以在 http://msdn.microsoft.com/en-us/library/system.random.aspx 找到。 - KristoferA

6

我需要类似于Python的secrets.token_hex函数。

如果您需要安全地获取随机字节,可以使用System.Security.Cryptography命名空间中的RNGCryptoServiceProvider,像这样:

using var csprng = new RNGCryptoServiceProvider();
var bytes = new byte[16];

csprng.GetNonZeroBytes(bytes); // or csprng.GetBytes(…)

使用LINQ将字节数组转换为十六进制字符串似乎是最易读的选项:

string.Join("", bytes.Select(b => b.ToString("x2"))); // or "X2" for upper case

输出的结果可能如下所示:
7fb70c709a5eed32d37ed5771f09c0fe

3

使用LINQ

private static readonly Random _RND = new Random();

public static string GenerateHexString(int digits) {
    return string.Concat(Enumerable.Range(0, digits).Select(_ => _RND.Next(16).ToString("X")));
}

2
这里有一个返回256位十六进制字符串(8x8=256)的示例:
private static string RandomHexString()
{
    // 64 character precision or 256-bits
    Random rdm = new Random();
    string hexValue = string.Empty;
    int num;

    for (int i = 0; i < 8; i++)
    {
        num = rdm.Next(0, int.MaxValue);
        hexValue += num.ToString("X8");
    }

    return hexValue;
}

如果连续调用随机十六进制字符串,它将不会是唯一的。 - Dainius Kreivys

2

如果你希望它具有加密安全性,应该使用RNGCryptoServiceProvider。

public static string BuildSecureHexString(int hexCharacters)
{
    var byteArray = new byte[(int)Math.Ceiling(hexCharacters / 2.0)];
    using (var rng = new RNGCryptoServiceProvider())
    {
        rng.GetBytes(byteArray);
    }
    return String.Concat(Array.ConvertAll(byteArray, x => x.ToString("X2")));
}

0
从.NET 8开始,即2023年11月14日至16日发布,您可以使用来自System.Security.Cryptography的新方法:
RandomNumberGenerator.GetHexString(int stringLength, bool lowercase = false);

Microsoft 表示:
创建一个由加密随机十六进制字符填充的字符串。
这应该是未来的最佳方法。

-1

创建一个长度为n(~n/2字节)的随机十六进制字符串:

var randBytes = new byte[n/2 + n%2>0?1:0];
new Random().NextBytes(randBytes);
var hex = BitConverter.ToString(randBytes).Replace("-", string.Empty).Substring(0,n);

你考虑过Base64字符串吗?根据你的应用程序,它们通常更有用。它们保证是ASCII并且每个输入字节提供约4/3个字符。要创建一个n个字符的字符串:

var randBytes = new byte[(n/4 + n%4>0?1:0)*3];
new Random().NextBytes(randBytes);
var base64 = Convert.ToBase64String(randBytes).Substring(0,n);

显然,如果您的应用程序不需要奇数个十六进制字符或不是4个字符的倍数的Base64,则可以省略.Substring(0,n)。

随意扩展示例,使Random()静态化,正如其他帖子中所建议的那样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接