Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不使用特定字符的随机字符_C#_Random_Ascii - Fatal编程技术网

C# 不使用特定字符的随机字符

C# 不使用特定字符的随机字符,c#,random,ascii,C#,Random,Ascii,我正在尝试创建一些类似于基本随机密码生成器的东西,包括大写、小写和数字,但出于某种原因 static void Main(string[] args) { bool validLength = false; int userDefinedLength = 0; Console.WriteLine("How many characters would you like your password to be?");

我正在尝试创建一些类似于基本随机密码生成器的东西,包括大写、小写和数字,但出于某种原因

        static void Main(string[] args)
    {
        bool validLength = false; 
        int userDefinedLength = 0;
        Console.WriteLine("How many characters would you like your password to be?");
        do 
        {
            try
            {
                userDefinedLength = int.Parse(Console.ReadLine());
                validLength = true;
                if (userDefinedLength < 3)
                {
                    Console.WriteLine("Please enter something larger than 3.");
                    validLength = false; 
                }
            }
            catch (Exception)
            {
                Console.WriteLine("Please input a valid integer length.");
            }
        } while (validLength == false);
        char[] passwordArray = new char[userDefinedLength]; 
        int asciiValue = 0;
        char asciiChar = ' ';
        bool validPassword = false; 
        Random ranAsciiGroup = new Random();
        Random ascValue = new Random(); 
        do
        {
            for (int i = 0; i < passwordArray.Length; i++) 
            {
                int randomAsc = 0;
                randomAsc = ranAsciiGroup.Next(1, 4);
                //Console.WriteLine(randomAsc);
                if (randomAsc == 1)
                {
                    asciiValue = ascValue.Next(65, 91);
                    //Console.WriteLine(asciiValue);
                }
                else if (randomAsc == 2) 
                {
                    asciiValue = ascValue.Next(97, 123);
                    //Console.WriteLine(asciiValue);
                }
                else if (randomAsc == 3) 
                {
                    asciiValue = ascValue.Next(48, 58);
                    //Console.WriteLine(asciiValue);
                }
                asciiChar = (char)asciiValue; 
                passwordArray[i] = asciiChar; 
                //validPassword = true;
            }


            bool isDigit = false; 
            bool isUpper = false;
            bool isLower = false;

            for (int i = 0; i < passwordArray.Length; i++) 
            {
                if (char.IsDigit(passwordArray[i]))
                {
                    isDigit = true; 
                }

                if (char.IsUpper(passwordArray[i]))
                {
                    isUpper = true; 
                }

                if (char.IsLower(passwordArray[i]))
                {
                    isLower = true; 
                }
            }

            if (isDigit == true && isUpper == true && isLower == true) 
            {
                validPassword = true; 
            }


        } while (validPassword == false); 

        Console.WriteLine("Your password is..."); 
        Console.ForegroundColor = ConsoleColor.DarkGreen;
        foreach (char c in passwordArray)
        {
            Console.Write(c);
        }
        Console.ReadLine();
    }

System.Random
类不是设计为强RNG,而是设计为快速RNG。如果你想要一个高质量的随机数发生器,你需要使用一个基于类的随机数发生器

它使用加密随机生成器作为现有随机类的内部

运行它会让我

MM77D5EDJ0OHOOE8KPPIY0TOC0HWQJPO37B4LFJ56LVCQVA4JE83J8BS8XEXX6ZCEr2OD8A70V2xFKIY0ROY3GN105RZT6PE8F2I


您可以看到它似乎没有您发现的偏见。

为您的RNG播种

别忘了给你的random实例植入种子

var random = new System.Random(Environment.TickCount);
而且,一个实例就足够了

消除重复

如果希望确保表示所有字符,可以使用不同的随机选择技术。例如,您可以生成一个非常长的字符串,其中包含您想要的所有字符,对其进行随机排序,然后获取前n个字符。这种方法将完全消除重复字符,并保证最终使用每个字符。例如:

using System;
using System.Linq;

public class Program
{
    static readonly Random _random = new System.Random(Environment.TickCount);
    const string dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklpmnopqrstuvwxyz0123456789!@#$%^&*()_+-=";

    static string GetPassword(int length)
    {
        return new String
            (
                dictionary
                   .OrderBy( a => _random.NextDouble() )
                   .Take(length)
                   .ToArray()
            );
    }

    public static void Main()
    {
        var s = GetPassword(30);
        Console.WriteLine(s);
    }
}
在本例中,我们将字符串视为可枚举的(是的,这是允许的),并使用LINQ方法对其随机排序,并取前n个字符。然后,我们将结果传递给包含答案的新
System.String
的构造函数

样本输出:

运行#1:

运行#2:

运行#3:

我觉得很随意

受控重复

当然,上述解决方案只允许字典中每个字符最多有一个实例。但也许你希望他们能够出现不止一次,但不要太多。如果您希望控制有限的可能重复次数,您可以做一些小的更改:

    static string GetPassword(int length, int maxRepeats)
    {
        return new String
            (
                Enumerable.Range(0, maxRepeats)
                   .SelectMany( i => dictionary )
                   .OrderBy( a => _random.NextDouble() )
                   .Take(length)
                   .ToArray()
            );
    }
在本例中,我们克隆字典
maxreats
次,并使用
SelectMany
将它们连接起来。然后我们对这个巨大的字符串进行随机排序,并取前n个字符作为密码


您使用的是
随机
错误,请看,我没有仔细查看,但您的代码似乎使用了小于6的数字,请看以下几个100个字符的示例:
2MT1l99JZT41VKEIHU47G42ZS1OVD6Q934A3MJASHG523C8SU1OIM0QJ9LEYL164W3IYH0G8W5R1I2JZGY6RDTJ526D3RQVJ9CZ
WSN5L11BZ72LP4UMPO2RMQW3WPC47P02XCAJITOITIHK2AOXYM2W431VAC7NUU6Z62TYUO49JN8E9EZM69HYX5X23
这实际上并不有趣,这是因为Random的同步实例。是的,我刚刚删除了Random的第二个实例,并在整个程序中使用了第一个实例。这似乎现在起作用了。下面是一个小例子,它给出了这种效果的一些直方图:您不需要手动为其设定种子。使用默认构造函数执行与您列出的完全相同的操作
!#t(hfTz0rB5cvKy1d$oeVI2mnsCba
y7Y(MB1pWH$wO5XPD0b+%Rkn9a4F!_
tH92lnh*sL+WOaTYR160&xiZpC5@G3
    static string GetPassword(int length, int maxRepeats)
    {
        return new String
            (
                Enumerable.Range(0, maxRepeats)
                   .SelectMany( i => dictionary )
                   .OrderBy( a => _random.NextDouble() )
                   .Take(length)
                   .ToArray()
            );
    }