Tuesday, September 7, 2010

C# Random Password Generator

Below is a class for you to plug into your projects.

It generates random passwords by using actual random seed and omits those pesky letters that look similar to one another.

You can reuse the class by passing in options such as password length and the different characters you want to include. And since its the source code, you can extend/adapt it to your needs.

Enjoy

This blog post has moved to my new blog, you are about to be redirected...



using System;
using System.Security.Cryptography;
 
 
namespace Security
{
    public enum RandomPasswordOptions
    {
        Alpha = 1,
        Numeric = 2,
        AlphaNumeric = Alpha + Numeric,
        AlphaNumericSpecial = 4
    }
 
    public class RandomPasswordGenerator
    {
        // Define default password length.
        private static int DEFAULT_PASSWORD_LENGTH = 8;
 
        //No characters that are confusing: i, I, l, L, o, O, 0, 1, u, v
 
        private static string PASSWORD_CHARS_Alpha = 
                                   "abcdefghjkmnpqrstwxyzABCDEFGHJKMNPQRSTWXYZ";
        private static string PASSWORD_CHARS_NUMERIC = "23456789";
        private static string PASSWORD_CHARS_SPECIAL = "*$-+?_&=!%{}/";
 
        #region Overloads
 
        /// 
        /// Generates a random password with the default length.
        /// 
        /// Randomly generated password.
        public static string Generate()
        {
            return Generate(DEFAULT_PASSWORD_LENGTH, 
                            RandomPasswordOptions.AlphaNumericSpecial);
        }
 
        /// 
        /// Generates a random password with the default length.
        /// 
        /// Randomly generated password.
        public static string Generate(RandomPasswordOptions option)
        {
            return Generate(DEFAULT_PASSWORD_LENGTH, option);
        }
 
        /// 
        /// Generates a random password with the default length.
        /// 
        /// Randomly generated password.
        public static string Generate(int passwordLength)
        {
            return Generate(DEFAULT_PASSWORD_LENGTH, 
                            RandomPasswordOptions.AlphaNumericSpecial);
        }
 
        /// 
        /// Generates a random password.
        /// 
        /// Randomly generated password.
        public static string Generate(int passwordLength, 
                                      RandomPasswordOptions option)
        {
            return GeneratePassword(passwordLength, option);
        }
 
        #endregion
 
 
        /// 
        /// Generates the password.
        /// 
        /// 
        private static string GeneratePassword(int passwordLength, 
                                               RandomPasswordOptions option)
        {
            if (passwordLength < 0) return null;
 
            var passwordChars = GetCharacters(option);
 
            if (string.IsNullOrEmpty(passwordChars)) return null;
 
            var password = new char[passwordLength];
 
            var random = GetRandom();
 
            for (int i = 0; i < passwordLength; i++)
            {
                var index = random.Next(passwordChars.Length);
                var passwordChar = passwordChars[index];
 
                password[i] = passwordChar;
            }
 
            return new string(password);
        }
 
 
 
        /// 
        /// Gets the characters selected by the option
        /// 
        /// 
        private static string GetCharacters(RandomPasswordOptions option)
        {
            switch (option)
            {
                case RandomPasswordOptions.Alpha:
                    return PASSWORD_CHARS_Alpha;
                case RandomPasswordOptions.Numeric:
                    return PASSWORD_CHARS_NUMERIC;
                case RandomPasswordOptions.AlphaNumeric:
                    return PASSWORD_CHARS_Alpha + PASSWORD_CHARS_NUMERIC;
                case RandomPasswordOptions.AlphaNumericSpecial:
                    return PASSWORD_CHARS_Alpha + PASSWORD_CHARS_NUMERIC + 
                                 PASSWORD_CHARS_SPECIAL;
                default:
                    break;
            }
            return string.Empty;
        }
        
        /// 
        /// Gets a random object with a real random seed
        /// 
        /// 
        private static Random GetRandom()
        {
            // Use a 4-byte array to fill it with random bytes and convert it then
            // to an integer value.
            byte[] randomBytes = new byte[4];
 
            // Generate 4 random bytes.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(randomBytes);
 
            // Convert 4 bytes into a 32-bit integer value.
            int seed = (randomBytes[0] & 0x7f) << 24 |
                        randomBytes[1] << 16 |
                        randomBytes[2] << 8 |
                        randomBytes[3];
 
            // Now, this is real randomization.
            return new Random(seed);
        }
 
 
    }
}