C# Exercises

Home AgriMetSoft About Contact

Random Password Generator in WinForms c#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Random_Password_Generator
  public partial class Form1 : Form
    public Form1()
    private void Generate_method1_Click(object sender, EventArgs e)
      richTextBox1.Text = Guid.NewGuid().ToString("d");

    private void Generate_method2_Click(object sender, EventArgs e)
      richTextBox2.Text = GenerateToken(10);
    private void Generate_method3_Click(object sender, EventArgs e)
      richTextBox3.Text = RandomPassword.Generate(10, 16);
    public string GenerateToken(int length)
      using (System.Security.Cryptography.RNGCryptoServiceProvider cryptRNG = new System.Security.Cryptography.RNGCryptoServiceProvider())
        byte[] tokenBuffer = new byte[length];
        return Convert.ToBase64String(tokenBuffer);

  public class RandomPassword
    // Define default min and max password lengths.
    private static int DEFAULT_MIN_PASSWORD_LENGTH = 8;
    private static int DEFAULT_MAX_PASSWORD_LENGTH = 10;

    // Define supported password characters divided into groups.
    // You can add (or remove) characters to (from) these groups.
    private static string PASSWORD_CHARS_LCASE = "abcdefgijkmnopqrstwxyz";
    private static string PASSWORD_CHARS_NUMERIC = "23456789";
    private static string PASSWORD_CHARS_SPECIAL = "*$-+?_&=!%{}/";

    public static string Generate()
      return Generate(DEFAULT_MIN_PASSWORD_LENGTH,

    public static string Generate(int length)
      return Generate(length, length);
    public static string Generate(int minLength,
                   int maxLength)
      // Make sure that input parameters are valid.
      if (minLength <= 0 || maxLength <= 0 || minLength > maxLength)
        return null;

      // Create a local array containing supported password characters
      // grouped by types. You can remove character groups from this
      // array, but doing so will weaken the password strength.
      char[][] charGroups = new char[][]
      // Use this array to track the number of unused characters in each
      // character group.
      int[] charsLeftInGroup = new int[charGroups.Length];

      // Initially, all characters in each group are not used.
      for (int i = 0; i < charsLeftInGroup.Length; i++)
        charsLeftInGroup[i] = charGroups[i].Length;

      // Use this array to track (iterate through) unused character groups.
      int[] leftGroupsOrder = new int[charGroups.Length];

      // Initially, all character groups are not used.
      for (int i = 0; i < leftGroupsOrder.Length; i++)
        leftGroupsOrder[i] = i;

      // Because we cannot use the default randomizer, which is based on the
      // current time (it will produce the same "random" number within a
      // second), we will use a random number generator to seed the
      // randomizer.

      // 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.
      System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();

      // Convert 4 bytes into a 32-bit integer value.
      int seed = BitConverter.ToInt32(randomBytes, 0);

      // Now, this is real randomization.
      Random random = new Random(seed);

      // This array will hold password characters.
      char[] password = null;

      // Allocate appropriate memory for the password.
      if (minLength < maxLength)
        password = new char[random.Next(minLength, maxLength + 1)];
        password = new char[minLength];

      // Index of the next character to be added to password.
      int nextCharIdx;

      // Index of the next character group to be processed.
      int nextGroupIdx;

      // Index which will be used to track not processed character groups.
      int nextLeftGroupsOrderIdx;

      // Index of the last non-processed character in a group.
      int lastCharIdx;

      // Index of the last non-processed group.
      int lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
      // Generate password characters one at a time.
      for (int i = 0; i < password.Length; i++)
        // If only one character group remained unprocessed, process it;
        // otherwise, pick a random character group from the unprocessed
        // group list. To allow a special character to appear in the
        // first position, increment the second parameter of the Next
        // function call by one, i.e. lastLeftGroupsOrderIdx + 1.
        if (lastLeftGroupsOrderIdx == 0)
          nextLeftGroupsOrderIdx = 0;
          nextLeftGroupsOrderIdx = random.Next(0,

        // Get the actual index of the character group, from which we will
        // pick the next character.
        nextGroupIdx = leftGroupsOrder[nextLeftGroupsOrderIdx];

        // Get the index of the last unprocessed characters in this group.
        lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;

        // If only one unprocessed character is left, pick it; otherwise,
        // get a random character from the unused character list.
        if (lastCharIdx == 0)
          nextCharIdx = 0;
          nextCharIdx = random.Next(0, lastCharIdx + 1);

        // Add this character to the password.
        password[i] = charGroups[nextGroupIdx][nextCharIdx];
        // If we processed the last character in this group, start over.
        if (lastCharIdx == 0)
          charsLeftInGroup[nextGroupIdx] =
        // There are more unprocessed characters left.
          // Swap processed character with the last unprocessed character
          // so that we don't pick it until we process all characters in
          // this group.
          if (lastCharIdx != nextCharIdx)
            char temp = charGroups[nextGroupIdx][lastCharIdx];
            charGroups[nextGroupIdx][lastCharIdx] =
            charGroups[nextGroupIdx][nextCharIdx] = temp;
          // Decrement the number of unprocessed characters in
          // this group.

        // If we processed the last group, start all over.
        if (lastLeftGroupsOrderIdx == 0)
          lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
        // There are more unprocessed groups left.
          // Swap processed group with the last unprocessed group
          // so that we don't pick it until we process all groups.
          if (lastLeftGroupsOrderIdx != nextLeftGroupsOrderIdx)
            int temp = leftGroupsOrder[lastLeftGroupsOrderIdx];
            leftGroupsOrder[lastLeftGroupsOrderIdx] =
            leftGroupsOrder[nextLeftGroupsOrderIdx] = temp;
          // Decrement the number of unprocessed groups.

      // Convert password characters into a string and return the result.
      return new string(password);

Download the project of Visual Studio 2013 in DropBox Download

How to use Random Password Generato in WinForms C#

List of Exercises