6

I am making a password generator that generates a random number, then I have it converted to a letter using ascii. Inside the for loop, I need the letters to convert a string instead of a list. It works, but it just displays random letters as a list.

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
    }
}
Christofer Eliasson
  • 32,939
  • 7
  • 74
  • 103
kevin
  • 65
  • 1
  • 7

7 Answers7

16
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() );

This isn't how I would build a password nor how I would generate random text, but this will give you a string and answer the original question.

As to how I would do this task:

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

For completeness sake, here's a Base62 algorithm which I use. Base62 has the advantage over the more commonly-used Base64 in that it does not include any special characters so it is easy to use in query strings, HTML, and JavaScript (with a few minor caveats). Of course, passwords shouldn't be used in any of those places, and you may want to include special characters to make a password more complex.

Regardless, here is how I convert random numbers to 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;
}

Lastly, I want to point out that passwords should very rarely be generated for any purpose, because that means they are being distributed in some form. Passwords should be hashed and salted; password resets should rely on random, expiring security tokens allowing the user a one-time reset. Passwords should never be emailed to a user; passwords should never be stored in plaintext or any reversible format.

For password reset token generation, the code I provided could work nicely because it produces a large, cryptographically random number encoded with a web-safe format. But even a hashed GUID would do the trick in that case.

Tim M.
  • 53,671
  • 14
  • 120
  • 163
  • +1 for the use of RNGCryptoServiceProvider; however, the rest of it is... well, not how I would have done it ;) The important part here is using a cryptographically secure pseudo-random number generator to produce a desired number of bytes and covert those to the allowable set of characters. – csharptest.net Dec 15 '11 at 20:22
  • @csharptest.net - Agreed, the bit conversion and Base62 algorithm is pretty esoteric and certainly not the simplest way of doing things. I wrote it when I needed a very fast implementation and this method gave the highest performance results. I posted it because I have had trouble finding an implementation in the past and Base62 is very useful for generating Javascript, HTML, and query string safe IDs (unlike base 64) and a larger unique number can be represented in fewer characters than base 10 or 16. – Tim M. Dec 15 '11 at 20:29
6
var sb = new StringBuilder();
for (int i = 0; i < length; i++) {
    sb.Append((char)Number());
}
string password = sb.ToString();
Console.WriteLine(password );

But I would change your Number() method to:

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

and then replace the line inside the loop:

sb.Append(GetRandomChar());
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • Thank you! That is quite a bit of material I am not used to, but that gives me something to study. – kevin Dec 15 '11 at 20:49
  • Working with StringBuilder is often more efficient than working directly on string, since operations like s = s + "x" always create a new string on the heap, which has to be collected by the system later. StringBuilder, however, maintains a buffer as work area that grows only when required. – Olivier Jacot-Descombes Dec 15 '11 at 21:14
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
    }
}
Otiel
  • 18,404
  • 16
  • 78
  • 126
doitdotnet
  • 31
  • 1
2

you can try this one

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);
        }
    }
}
Glory Raj
  • 17,397
  • 27
  • 100
  • 203
1

just define a string at near int x... like String Password = "";

and in the if statement appent the keyyword.

if (length > 0)
{
Console.WriteLine(num);
Password+=num
}
user999822
  • 445
  • 1
  • 9
  • 17
0

I found the following post useful when I had to create a method to generate a random password: https://stackoverflow.com/a/730352/1015289

However, when I wanted to create a short 'validation' style code which would be emailed to a user to confirm their details, I wanted to restrict the validation code to only 8 characters.

For this I used the following:

string validationCoce = Guid.NewGuid().ToString().Substring(0, 8);

This would be stored in a database which also held the users email, both encrypted before being stored for security purposes.

Both the email and validation code were required to validate the users account.

Hope either of the above help?

Kind Regards, Wayne

Community
  • 1
  • 1
Wayne Phipps
  • 2,019
  • 6
  • 26
  • 31
-1

use Console.Write() instead of Console.WriteLine() otherwise append to some string and print outside the loop

Prakash Mani
  • 115
  • 1
  • 2
  • 13