【问题标题】:Generate password using a for loop使用 for 循环生成密码
【发布时间】:2012-01-21 11:37:15
【问题描述】:

我正在制作一个生成随机数的密码生成器,然后我使用 ascii 将其转换为字母。在 for 循环中,我需要字母来转换字符串而不是列表。它有效,但它只是将随机字母显示为列表。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

class MainClass
{
    static void Main()
    {
        int x = 1;
        int length;
        string a = "Press any key to continue";
        object num;


        while (x == 1)

        {
            Console.WriteLine("How many Characters would you like the Password to be? (Press -1 to Stop)");
            length = Convert.ToInt32(Console.ReadLine());
            try
            {
                for (int i = 0; i < length; i++)
                {
                    int num1 = Number();
                    Int32 ASCII = num1;
                    num = (char)num1;

                    if (length > 0)
                    {
                        Console.WriteLine(num);
                    }
                }
            }
            catch
            {
                Console.WriteLine(a);
            }

            if (length == -1)
                break;
        }
    }
    static Random _r = new Random();
    static int Number()
    {
        return _r.Next(65, 90); // decimal
    }
}

【问题讨论】:

    标签: c#


    【解决方案1】:
    StringBuilder sb = new StringBuilder();
    
    for( int i = 0; i < length; i++ )
    {
        int num1 = Number();
        Int32 ASCII = num1;
        num = (char)num1;
    
        sb.Append( num );
    }
    
    Console.WriteLine( sb.ToString() );
    

    这不是我构建密码的方式,也不是我生成随机文本的方式,但这会给你一个字符串并回答原始问题。

    至于我将如何完成这项任务:

    System.Security.Cryptography.RNGCryptoServiceProvider _crypto = new System.Security.Cryptography.RNGCryptoServiceProvider();
    
    byte[] bytes = new byte[8]; // this array can be larger if desired
    _crypto.GetBytes( bytes );
    
    ulong randomNumber = (ulong)BitConverter.ToInt64( bytes, 0 );
    
    // convert to a string with the encoding of your choice; I prefer Base 62
    

    为了完整起见,这是我使用的 Base62 算法。 Base62 与更常用的 Base64 相比具有优势,因为它不包含任何特殊字符,因此很容易在查询字符串、HTML 和 JavaScript 中使用(有一些小警告)。当然,这些地方都不应该使用密码,您可能希望包含特殊字符以使密码更复杂。

    不管怎样,下面是我将随机数转换为 Base62 的方法。

    private static readonly char[] _base62Characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
    
    public static string ToBase62String( long value )
    {
        if( value < 0L )
        {
            throw new ArgumentException( "Number must be zero or greater." );
        }
    
        if( value == 0 )
        {
            return "0";
        }
    
        string retVal = "";
    
        while( value > 0 )
        {
            retVal = _base62Characters[value % 62] + retVal;
            value = value / 62;
        }
    
        return retVal;
    }
    

    最后,我想指出,密码应该很少出于任何目的而生成,因为这意味着它们是以某种形式分发的。密码应该被散列和加盐;密码重置应该依赖于随机的、过期的安全令牌,允许用户一次性重置。永远不要将密码通过电子邮件发送给用户;密码不应以明文或任何可逆格式存储。

    对于密码重置令牌生成,我提供的代码可以很好地工作,因为它会生成一个大的、以网络安全格式编码的加密随机数。但在这种情况下,即使是散列的 GUID 也可以解决问题。

    【讨论】:

    • +1 用于 RNGCryptoServiceProvider;但是,其余部分是......好吧,不是我会怎么做;)这里的重要部分是使用加密安全的伪随机数生成器来产生所需数量的字节并将这些字节转换为允许的集合字符。
    • @csharptest.net - 同意,位转换和 Base62 算法非常深奥,当然不是最简单的做事方式。当我需要一个非常快速的实现时,我写了它,这种方法给出了最高的性能结果。我发布它是因为我过去很难找到一个实现,而且 Base62 对于生成 Javascript、HTML 和查询字符串安全 ID(与 base 64 不同)非常有用,并且可以用比 base 10 更少的字符来表示更大的唯一数字或16.
    【解决方案2】:
    var sb = new StringBuilder();
    for (int i = 0; i < length; i++) {
        sb.Append((char)Number());
    }
    string password = sb.ToString();
    Console.WriteLine(password );
    

    但我会将您的 Number() 方法更改为:

    private static char GetRandomChar()
    {
        return (char)_r.Next(65, 90);
    }
    

    然后替换循环内的行:

    sb.Append(GetRandomChar());
    

    【讨论】:

    • 谢谢!这是相当多的材料我不习惯,但这给了我一些学习的东西。
    • 使用 StringBuilder 通常比直接处理字符串更有效,因为像 s = s + "x" 这样的操作总是在堆上创建一个新的字符串,以后必须由系统收集。然而,StringBuilder 维护一个缓冲区作为工作区,仅在需要时才会增长。
    【解决方案3】:
    //You have to append the values generated by the RandomNumber in to your password variable
    
    class MainClass
    {
        static void Main()
        {
            int x = 1;
            int length;
            string a = "Press any key to continue";
            string num=string.Empty;
    
    
            while (x == 1)
            {
                Console.WriteLine("How many Characters would you like the Password to be? (Press -1 to Stop)");
                length = Convert.ToInt32(Console.ReadLine());
                try
                {
                    for (int i = 0; i < length; i++)
                    {
                        int num1 = Number();
                        Int32 ASCII = num1;
    
                        num =num+ ((char)num1);
    
                    }
                    Console.WriteLine(num);
                }
                catch
                {
                    Console.WriteLine(a);
                }
    
                if (length == -1)
                    break;
            }
        }
        static Random _r = new Random();
        static int Number()
        {
            return _r.Next(65, 90); // decimal
        }
    }
    

    【讨论】:

      【解决方案4】:

      你可以试试这个

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      
      namespace PasswordSample
      {
          class Program
          {
              static void Main(string[] args)
              {
                  Console.WriteLine("Generated password: {0}", GeneratePassword(12, true));
              }
      
              /// <summary>
              /// Generate a random password
              /// </summary>
              /// <param name="pwdLenght">Password lenght</param>
              /// <param name="nonAlphaNumericChars">Indicates if password will include non alpha-numeric</param>
              /// <returns>Return a password</returns>
              private static String GeneratePassword(int pwdLenght, bool nonAlphaNumericChars)
              {
                  // Allowed characters
                  String allowedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
      
                  if (nonAlphaNumericChars)
                  {
                      // Add non-alphanumeric chars
                      allowedChars += "-&@#%!*$?_";
                  }
      
                  char[] passwordChars = new char[pwdLenght];
                  Random rnd = new Random();
      
                  // Generate a random password
                  for (int i = 0; i < pwdLenght; i++)
                      passwordChars[i] = allowedChars[rnd.Next(0, allowedChars.Length)];
      
                  return new String(passwordChars);
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        只需在 int x 附近定义一个字符串... 喜欢 字符串密码 = "";

        并在 if 语句中附加关键字。

        if (length > 0)
        {
        Console.WriteLine(num);
        Password+=num
        }
        

        【讨论】:

          【解决方案6】:

          当我必须创建一个生成随机密码的方法时,我发现以下帖子很有用: https://stackoverflow.com/a/730352/1015289

          但是,当我想创建一个简短的“验证”样式代码并通过电子邮件发送给用户以确认他们的详细信息时,我想将验证代码限制为仅 8 个字符。

          为此,我使用了以下内容:

          字符串验证Coce = Guid.NewGuid().ToString().Substring(0, 8);

          这将存储在一个数据库中,该数据库还保存了用户的电子邮件,为了安全起见,在存储之前都进行了加密。

          验证用户帐户时需要电子邮件和验证码。

          希望以上任何一种帮助?

          亲切的问候,韦恩

          【讨论】:

            【解决方案7】:

            使用 Console.Write() 代替 Console.WriteLine() 否则附加到一些字符串并在循环外打印

            【讨论】:

              猜你喜欢
              • 2016-08-12
              • 2013-12-16
              • 1970-01-01
              • 2020-08-26
              • 1970-01-01
              • 2019-03-09
              • 2021-01-14
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多