Monday, April 27, 2009

Read password C# console

Method to read password from console:



using System.Collections;
...
public static string ReadPassword() {

Stack pass = new Stack();

for (ConsoleKeyInfo consKeyInfo = Console.ReadKey(true);
consKeyInfo.Key != ConsoleKey.Enter; consKeyInfo = Console.ReadKey(true))
{
if (consKeyInfo.Key == ConsoleKey.Backspace)
{
try
{
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
Console.Write(" ");
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
pass.Pop();
}
catch (InvalidOperationException)
{
Console.SetCursorPosition(Console.CursorLeft + 1, Console.CursorTop);
}
}
else {
Console.Write("*");
pass.Push(consKeyInfo.KeyChar.ToString());
}
}
string[] password = (string[])pass.ToArray();
Array.Reverse(password);
return string.Join(string.Empty, password);

}

6 comments:

  1. But , you need to change your code : a cast of Object[] to string[] is not possible but Object to string can be done. So can you add this code :

    private static string[] Transform(object[] array)
    {
    string[] final = new string[array.Length];

    for (int i = 0; i < array.Length; i++)
    {
    final[i] = (string)array[i];
    }

    return final;
    }

    and modify string[] password = (string[])pass.ToArray();
    to string[] password = Transform(pass.ToArray());

    Bay !

    ReplyDelete
  2. Thanks for this example. I am able to carry out my task easily.

    ReplyDelete
  3. Bit late to the party, but I just thought I'd mention an alternative means of transforming the stack to a string.

    The number of elements in the stack is Pass.Count, and we can use Pass.CopyTo() to copy the contents of the stack to an Array:

    string[] password = new string[Pass.Count];
    Pass.CopyTo(password,0);

    The Stack is in reverse order, so we flip it (as in the original code)

    Array.Reverse(password);

    But then we can use string.Join straight on the array:

    string userPass = string.Join(string.Empty, password);

    ReplyDelete
    Replies
    1. Later answer, but this is a great modification!

      Delete
  4. Any reason why you don't just use a stringbuilder?

    Also - needed to handle the case where user presses backspace with nothing on the stack (or in the stringbuilder)

    1: public static string ReadPassword()
    2: {
    3: StringBuilder sb = new StringBuilder();
    4: for (ConsoleKeyInfo consKeyInfo = Console.ReadKey(true); consKeyInfo.Key != ConsoleKey.Enter; consKeyInfo = Console.ReadKey(true))
    5: {
    6: if (consKeyInfo.Key == ConsoleKey.Backspace)
    7: {
    8: if (sb.Length > 0)
    9: {
    10: try
    11: {
    12: Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
    13: Console.Write(" ");
    14: Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
    15: sb.Remove(sb.Length - 1, 1);
    16: }
    17: catch (InvalidOperationException)
    18: {
    19: Console.SetCursorPosition(Console.CursorLeft + 1, Console.CursorTop);
    20: }
    21: }
    22: }
    23: else
    24: {
    25: Console.Write("*");
    26: sb.Append(consKeyInfo.KeyChar.ToString());
    27: }
    28: }
    29: return sb.ToString();
    30: }

    ReplyDelete