c# – 如何使用RNGCryptoServiceProvider根据我的首选字符创建随机密码?

我目前正在创建一个随机密码是这样的:
public static int getRandomNumber(int maxNumber)
    {
        if (maxNumber < 1)
            throw new System.Exception("The maxNumber value should be greater than 1");
        byte[] b = new byte[4];
        new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(b);
        int seed = (b[0] & 0x7f) << 24 | b[1] << 16 | b[2] << 8 | b[3];
        System.Random r = new System.Random(seed);
        return r.Next(1,maxNumber);
    }

一些可能的问题?这是一个静态函数,有一些奇怪的种子模式可能不安全,仍然使用System.Random().

使用上面的随机数生成器,我以这种低效的方式创建一个字符串:

validCharacters = "abcdefghjkmnoxyz023456789#!@";

然后使用有效数组循环并获取“createPassword(length)”类型字符串(注意使用不包含容错字符的字符集,如1 i等).

这是如何做到的,还是有更简单,更安全,更有效的方式?

解决方法

为了生成随机数,您可以返回种子的剩余部分除以maxNumber:
public static int getRandomNumber(int maxNumber)
{
    if (maxNumber < 1)
        throw new System.Exception("The maxNumber value should be greater than 1");
    byte[] b = new byte[4];
    new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(b);
    int seed = (b[0] & 0x7f) << 24 | b[1] << 16 | b[2] << 8 | b[3];
    return seed % maxNumber;
}

在这种情况下,maxNumber是独占的,这也是Random.Next(maxNumber)的工作原理.

编辑

来自@Servy的评论非常有趣,并引导我阅读2007年9月MSDN杂志上发表的题为“来自CryptoRandom的故事”的Stephen Toub和Shawn Farkas的一篇文章,可以下载here,其中有一个使用RNGCryptoServiceProvider重新实现Random的例子这有偏见的解决方法.我在这里已经包含了它们的实现,因为源代码的格式非常讨厌,但是文章值得阅读它背后的原因.

public class CryptoRandom : Random
{
    private RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider();
    private byte[] _uint32Buffer = new byte[4];
    public CryptoRandom() { }
    public CryptoRandom(Int32 ignoredSeed) { }
    public override Int32 Next()
    {
        _rng.GetBytes(_uint32Buffer);
        return BitConverter.ToInt32(_uint32Buffer,0) & 0x7FFFFFFF;
    }
    public override Int32 Next(Int32 maxValue)
    {
        if (maxValue < 0) throw new ArgumentOutOfRangeException("maxValue");
        return Next(0,maxValue);
    }
    public override Int32 Next(Int32 minValue,Int32 maxValue)
    {
        if (minValue > maxValue) throw new ArgumentOutOfRangeException("minValue");
        if (minValue == maxValue) return minValue;
        Int64 diff = maxValue - minValue;
        while (true)
        {
            _rng.GetBytes(_uint32Buffer);
            UInt32 rand = BitConverter.ToUInt32(_uint32Buffer,0);
            Int64 max = (1 + (Int64)UInt32.MaxValue);
            Int64 remainder = max % diff;
            if (rand < max - remainder)
            {
                return (Int32)(minValue + (rand % diff));
            }
        }
    }
    public override double NextDouble()
    {
        _rng.GetBytes(_uint32Buffer);
        UInt32 rand = BitConverter.ToUInt32(_uint32Buffer,0);
        return rand / (1.0 + UInt32.MaxValue);
    }
    public override void NextBytes(byte[] buffer)
    {
        if (buffer == null) throw new ArgumentNullException("buffer");
        _rng.GetBytes(buffer);
    }
}

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

相关推荐


c语言数组越界会怎么样
c语言指针怎么等于数组
c语言数组怎么存入文字
c语言中怎么显示数组
c语言数组元素怎么选
c语言数组怎么累加
c语言数组符号怎么输入
c语言怎么用长数组
c语言数组函数怎么输入
c语言数组怎么去掉差异
c语言怎么求解数组
c语言数组怎么用变量
c语言怎么申明数组
c语言怎么控制数组
c语言怎么计算数组长度
c语言数组怎么插星号
c语言数组怎么加长度
c语言中怎么输出数组
c语言怎么记住数组边界
c语言数组怎么输入符号