แอปพลิเคชั่นคอนโซลกำบังรหัสผ่าน


201

ฉันลองรหัสต่อไปนี้ ...

string pass = "";
Console.Write("Enter your password: ");
ConsoleKeyInfo key;

do
{
    key = Console.ReadKey(true);

    // Backspace Should Not Work
    if (key.Key != ConsoleKey.Backspace)
    {
        pass += key.KeyChar;
        Console.Write("*");
    }
    else
    {
        Console.Write("\b");
    }
}
// Stops Receving Keys Once Enter is Pressed
while (key.Key != ConsoleKey.Enter);

Console.WriteLine();
Console.WriteLine("The Password You entered is : " + pass);

แต่วิธีนี้ฟังก์ชั่น backspace ไม่ทำงานในขณะที่พิมพ์รหัสผ่าน ข้อเสนอแนะใด ๆ


11
ฉันขอแนะนำให้คุณอย่าสะท้อนสิ่งใด ๆ กลับไปที่คอนโซลเพราะมันจะเปิดเผยความยาวของรหัสผ่าน
เรย์เฉิง

8
@RayCheng - ยุติธรรมพอ แต่มีส่วนต่อประสานผู้ใช้น้อยมาก (นอกเหนือจากระบบ Unix บางระบบ) ไม่ต้องพูดอะไรเลย สำหรับประสบการณ์ของผู้ใช้ที่สอดคล้องกับแอพและเว็บไซต์อื่น ๆ การแสดงอักขระ * น่าจะดีที่สุด
Stephen Holt

4
@StephenHolt ฉันค่อนข้างมั่นใจว่าการป้อนรหัสผ่านตามเทอร์มินัลทุกครั้งที่ฉันพบเคยเลือกที่จะสะท้อนสิ่งใด ๆ จากประโยชน์ด้านความปลอดภัยและความจริงที่ว่านี่คือการประชุมที่รู้จักกันดีในโลกของ Unix ฉันคิดว่าเป็นการส่วนตัวไม่มีทางเลือกที่ถูกต้องเว้นแต่คุณเชื่อว่าฐานผู้ใช้ของคุณมีแนวโน้มที่จะไม่คุ้นเคยกับการใช้เทอร์มินัล อาจเป็นการดีที่สุดที่จะใช้ GUI แทน)
Ajedi32

คำตอบ:


225

Console.Write("\b \b");จะลบอักขระดอกจันออกจากหน้าจอ แต่คุณไม่มีรหัสใด ๆ ในelseบล็อกของคุณที่จะลบอักขระที่ป้อนไว้ก่อนหน้านี้ออกจากpassตัวแปรสตริงของคุณ

นี่คือรหัสการทำงานที่เกี่ยวข้องซึ่งควรทำสิ่งที่คุณต้องการ:

string pass = "";
do
{
    ConsoleKeyInfo key = Console.ReadKey(true);
    // Backspace Should Not Work
    if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter)
    {
        pass += key.KeyChar;
        Console.Write("*");
    }
    else
    {
        if (key.Key == ConsoleKey.Backspace && pass.Length > 0)
        {
            pass = pass.Substring(0, (pass.Length - 1));
            Console.Write("\b \b");
        }
        else if(key.Key == ConsoleKey.Enter)
        {
            break;
        }
    }
} while (true);

2
โอ้ฉันคิดว่า \ b \ b จะพาฉันไปสองที่กลับมา อย่างไรก็ตามเรื่องนี้ดูเหมือนว่าจะทำงานได้อย่างสมบูรณ์
Mohammad Nadeem

8
@Nadeem: หมายเหตุอักขระเว้นวรรค ( ' ') ระหว่างอักขระ backspace ( '\b') "\b \b"นำคุณกลับมาที่หนึ่งแล้วพิมพ์เว้นวรรค (ซึ่งจะพาคุณไปข้างหน้าหนึ่งที่) แล้วนำคุณกลับมาอีกครั้งดังนั้นคุณจึงจบลงด้วย'*'ตัวละครที่ถูกลบ
dtb

14
@Nadeem - ครั้งแรก\bย้ายเคอร์เซอร์กลับหนึ่งตำแหน่ง (ตอนใต้ที่ผ่านมา*ถ่าน. [space]ตัวอักษร "พิมพ์มากกว่า" ดอกจัน แต่ยังย้ายเคอร์เซอร์ตัวละครตัวหนึ่งไปข้างหน้าอีกครั้งเพื่อที่ผ่านมา\bย้ายกลับเคอร์เซอร์ไปที่ผ่านมา*ใช้ในการ เป็น! (วุ้ย - หวังว่าเหมาะสม!)
CraigTP

3
if (pass.Length > 0)ควรจะif (key.Key == ConsoleKey.Backspace && pass.Length > 0)มิฉะนั้นคุณจะไม่ได้รับตัวอักษรตัวสุดท้ายของรหัสผ่าน ..
MemphiZ

9
หากคุณไม่ต้องการให้ผู้ใช้สามารถที่จะควบคุมตัวละครเขียน (เช่น F5 หรือหนี) คุณสามารถแทนที่ด้วยif (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter) if (!char.IsControl(key.KeyChar))
Safron

90

สำหรับสิ่งนี้คุณควรใช้System.Security.SecureString

public SecureString GetPassword()
{
    var pwd = new SecureString();
    while (true)
    {
        ConsoleKeyInfo i = Console.ReadKey(true);
        if (i.Key == ConsoleKey.Enter)
        {
            break;
        }
        else if (i.Key == ConsoleKey.Backspace)
        {
            if (pwd.Length > 0)
            {
                pwd.RemoveAt(pwd.Length - 1);
                Console.Write("\b \b");
            }
        }
        else if (i.KeyChar != '\u0000' ) // KeyChar == '\u0000' if the key pressed does not correspond to a printable character, e.g. F1, Pause-Break, etc
        {
            pwd.AppendChar(i.KeyChar);
            Console.Write("*");
        }
    }
    return pwd;
}

มันจะพาฉันไปสองที่เท่านั้น แต่สิ่งที่ฉันต้องการคือเมื่อฉันกด Backspace ควรลบอักขระตัวสุดท้าย เช่นเดียวกับฟังก์ชั่นดั้งเดิมของ Backspace
Mohammad Nadeem

1
ฉันต้องการที่จะรังif( pwd.Length > 0)เข้าไปในคำสั่งอื่นเป็นครั้งแรกที่จะหยุดคนลบคำถาม :)
Dead.Rabit

1
เช่นเดียวกับความคิดเห็นของ Safron เกี่ยวกับคำตอบที่ยอมรับในปัจจุบันelseประโยคสุดท้ายจะได้รับประโยชน์จากการทดสอบif (!char.IsControl(i.KeyChar))(หรืออย่างน้อยที่สุดif (i.KeyChar != '\u0000'))
Peter Taylor

1
ฉันจะเปลี่ยนรหัสผ่านนั้นเป็นสตริงได้อย่างไร
Joseph Kreifels II


47

โซลูชันที่สมบูรณ์วานิลลา C # .net 3.5+

ตัดและวาง :)

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

    namespace ConsoleReadPasswords
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.Write("Password:");

                string password = Orb.App.Console.ReadPassword();

                Console.WriteLine("Sorry - I just can't keep a secret!");
                Console.WriteLine("Your password was:\n<Password>{0}</Password>", password);

                Console.ReadLine();
            }
        }
    }

    namespace Orb.App
    {
        /// <summary>
        /// Adds some nice help to the console. Static extension methods don't exist (probably for a good reason) so the next best thing is congruent naming.
        /// </summary>
        static public class Console
        {
            /// <summary>
            /// Like System.Console.ReadLine(), only with a mask.
            /// </summary>
            /// <param name="mask">a <c>char</c> representing your choice of console mask</param>
            /// <returns>the string the user typed in </returns>
            public static string ReadPassword(char mask)
            {
                const int ENTER = 13, BACKSP = 8, CTRLBACKSP = 127;
                int[] FILTERED = { 0, 27, 9, 10 /*, 32 space, if you care */ }; // const

                var pass = new Stack<char>();
                char chr = (char)0;

                while ((chr = System.Console.ReadKey(true).KeyChar) != ENTER)
                {
                    if (chr == BACKSP)
                    {
                        if (pass.Count > 0)
                        {
                            System.Console.Write("\b \b");
                            pass.Pop();
                        }
                    }
                    else if (chr == CTRLBACKSP)
                    {
                        while (pass.Count > 0)
                        {
                            System.Console.Write("\b \b");
                            pass.Pop();
                        }
                    }
                    else if (FILTERED.Count(x => chr == x) > 0) { }
                    else
                    {
                        pass.Push((char)chr);
                        System.Console.Write(mask);
                    }
                }

                System.Console.WriteLine();

                return new string(pass.Reverse().ToArray());
            }

            /// <summary>
            /// Like System.Console.ReadLine(), only with a mask.
            /// </summary>
            /// <returns>the string the user typed in </returns>
            public static string ReadPassword()
            {
                return Orb.App.Console.ReadPassword('*');
            }
        }
    }

3
มันอาจเป็นเรื่องยากมากขึ้น :) จะไม่ทำงานบน Mac / Linux เพราะบรรทัดใหม่ไม่เป็นที่รู้จัก Environment.NewLine มีสตริงสำหรับการขึ้นบรรทัดใหม่ ดังนั้นฉันจึงแก้ไขสิ่งนี้เป็น: ในขณะที่ (! Environment.NewLine.Contains (chr = System.Console.ReadKey (จริง) .KeyChar))
Hugo Logmans

18

ใช้คำตอบที่ดีที่สุดรวมถึงคำแนะนำจากความคิดเห็นและแก้ไขเพื่อใช้ SecureString แทน String ทดสอบสำหรับปุ่มควบคุมทั้งหมดและไม่ผิดพลาดหรือเขียน "*" พิเศษลงบนหน้าจอเมื่อความยาวรหัสผ่านเป็น 0 ทางออกของฉันคือ:

public static SecureString getPasswordFromConsole(String displayMessage) {
    SecureString pass = new SecureString();
    Console.Write(displayMessage);
    ConsoleKeyInfo key;

    do {
        key = Console.ReadKey(true);

        // Backspace Should Not Work
        if (!char.IsControl(key.KeyChar)) {
            pass.AppendChar(key.KeyChar);
            Console.Write("*");
        } else {
            if (key.Key == ConsoleKey.Backspace && pass.Length > 0) {
                pass.RemoveAt(pass.Length - 1);
                Console.Write("\b \b");
            }
        }
    }
    // Stops Receving Keys Once Enter is Pressed
    while (key.Key != ConsoleKey.Enter);
    return pass;
}

15

ฉันจะละเว้นอักขระควบคุมและจัดการการตัดบรรทัด:

public static string ReadLineMasked(char mask = '*')
{
    var sb = new StringBuilder();
    ConsoleKeyInfo keyInfo;
    while ((keyInfo = Console.ReadKey(true)).Key != ConsoleKey.Enter)
    {
        if (!char.IsControl(keyInfo.KeyChar))
        {
            sb.Append(keyInfo.KeyChar);
            Console.Write(mask);
        }
        else if (keyInfo.Key == ConsoleKey.Backspace && sb.Length > 0)
        {
            sb.Remove(sb.Length - 1, 1);

            if (Console.CursorLeft == 0)
            {
                Console.SetCursorPosition(Console.BufferWidth - 1, Console.CursorTop - 1);
                Console.Write(' ');
                Console.SetCursorPosition(Console.BufferWidth - 1, Console.CursorTop - 1);
            }
            else Console.Write("\b \b");
        }
    }
    Console.WriteLine();
    return sb.ToString();
}

ทำงานได้อย่างสมบูรณ์แบบ คุณอาจต้องเพิ่มรหัสเพื่อให้DELETE ตัวละครลบข้อความที่ป้อนทั้งหมด ลำดับที่สำคัญของมันคือรหัสถ่านของมันคือCTRL + BACKSPACE 0x7f
Alex Essilfie

9

อินพุตคอนโซลการอ่านเป็นเรื่องยากคุณต้องจัดการคีย์พิเศษเช่น Ctrl, Alt, เคอร์เซอร์คีย์และ Backspace / Delete ในบางรูปแบบแป้นพิมพ์เช่นแป้นพิมพ์ภาษาสวีเดนจำเป็นต้องใส่รหัสที่มีอยู่บนแป้นพิมพ์ของสหรัฐอเมริกาโดยตรง ฉันเชื่อว่าพยายามจัดการสิ่งนี้โดยใช้ "ระดับต่ำ"Console.ReadKey(true)นั้นยากมากดังนั้นวิธีที่ง่ายที่สุดและแข็งแกร่งที่สุดคือการปิดใช้งาน "คอนโซลอินพุต echo" ในระหว่างการป้อนรหัสผ่านโดยใช้ WINAPI เล็กน้อย

ตัวอย่างด้านล่างขึ้นอยู่กับคำตอบในการอ่านรหัสผ่านจากคำถามมาตรฐาน :: cin

    private enum StdHandle
    {
        Input = -10,
        Output = -11,
        Error = -12,
    }

    private enum ConsoleMode
    {
        ENABLE_ECHO_INPUT = 4
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr GetStdHandle(StdHandle nStdHandle);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out int lpMode);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetConsoleMode(IntPtr hConsoleHandle, int dwMode);

    public static string ReadPassword()
    {
        IntPtr stdInputHandle = GetStdHandle(StdHandle.Input);
        if (stdInputHandle == IntPtr.Zero)
        {
            throw new InvalidOperationException("No console input");
        }

        int previousConsoleMode;
        if (!GetConsoleMode(stdInputHandle , out previousConsoleMode))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not get console mode.");
        }

        // disable console input echo
        if (!SetConsoleMode(stdInputHandle , previousConsoleMode & ~(int)ConsoleMode.ENABLE_ECHO_INPUT))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not disable console input echo.");
        }

        // just read the password using standard Console.ReadLine()
        string password = Console.ReadLine();

        // reset console mode to previous
        if (!SetConsoleMode(stdInputHandle , previousConsoleMode))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not reset console mode.");
        }

        return password;
    }

9

ซึ่งจะปกปิดรหัสผ่านที่มีช่องสี่เหลี่ยมสีแดงจากนั้นเปลี่ยนกลับเป็นสีเดิมเมื่อป้อนรหัสผ่านแล้ว

มันไม่ได้หยุดผู้ใช้จากการใช้การคัดลอก / วางเพื่อรับรหัสผ่าน แต่ถ้ามันเป็นเพียงเกี่ยวกับการหยุดใครบางคนมองข้ามไหล่ของคุณนี่เป็นทางออกที่ดีอย่างรวดเร็ว

Console.Write("Password ");
ConsoleColor origBG = Console.BackgroundColor; // Store original values
ConsoleColor origFG = Console.ForegroundColor;

Console.BackgroundColor = ConsoleColor.Red; // Set the block colour (could be anything)
Console.ForegroundColor = ConsoleColor.Red;

string Password = Console.ReadLine(); // read the password

Console.BackgroundColor= origBG; // revert back to original
Console.ForegroundColor= origFG;

ปัญหาเดียวคือถ้าคุณย้อนกลับพื้นหลังที่คุณมีตัวอักษรอยู่สีแดง ฉันอยากจะไปกับการตั้งค่า ForegroundColor เป็น origBG เพื่อให้มีการป้อนรหัสผ่านสไตล์ Linux
mababin

1
คุณสามารถทำได้Console.CursorVisible=falseและตั้งค่ากลับเป็นค่าก่อนหน้าหลังจาก สิ่งนี้จะป้องกันไม่ให้ใครบางคนถึงจุดสูงสุดที่ความยาวรหัสผ่าน
mababin

6

ฉันพบข้อผิดพลาดในวานิลลา C # 3.5. NET ของ shermy ซึ่งใช้งานได้ดี ฉันยังได้รวม Damian Leszczyński - แนวคิด SecureString ของ Vash ไว้ที่นี่ แต่คุณสามารถใช้สตริงธรรมดาได้ถ้าต้องการ

ข้อผิดพลาด: ถ้าคุณกด backspace ในระหว่างการถามรหัสผ่านและความยาวปัจจุบันของรหัสผ่านคือ 0 ดังนั้นเครื่องหมายดอกจันจะถูกใส่อย่างไม่ถูกต้องในรูปแบบรหัสผ่าน เพื่อแก้ไขข้อผิดพลาดนี้แก้ไขวิธีการดังต่อไปนี้

    public static string ReadPassword(char mask)
    {
        const int ENTER = 13, BACKSP = 8, CTRLBACKSP = 127;
        int[] FILTERED = { 0, 27, 9, 10 /*, 32 space, if you care */ }; // const


        SecureString securePass = new SecureString();

        char chr = (char)0;

        while ((chr = System.Console.ReadKey(true).KeyChar) != ENTER)
        {
            if (((chr == BACKSP) || (chr == CTRLBACKSP)) 
                && (securePass.Length > 0))
            {
                System.Console.Write("\b \b");
                securePass.RemoveAt(securePass.Length - 1);

            }
            // Don't append * when length is 0 and backspace is selected
            else if (((chr == BACKSP) || (chr == CTRLBACKSP)) && (securePass.Length == 0))
            {
            }

            // Don't append when a filtered char is detected
            else if (FILTERED.Count(x => chr == x) > 0)
            {
            }

            // Append and write * mask
            else
            {
                securePass.AppendChar(chr);
                System.Console.Write(mask);
            }
        }

        System.Console.WriteLine();
        IntPtr ptr = new IntPtr();
        ptr = Marshal.SecureStringToBSTR(securePass);
        string plainPass = Marshal.PtrToStringBSTR(ptr);
        Marshal.ZeroFreeBSTR(ptr);
        return plainPass;
    }

4

นี่คือรุ่นที่เพิ่มการรองรับEscapeคีย์ (ซึ่งคืนค่าnullสตริง)

public static string ReadPassword()
{
    string password = "";
    while (true)
    {
        ConsoleKeyInfo key = Console.ReadKey(true);
        switch (key.Key)
        {
            case ConsoleKey.Escape:
                return null;
            case ConsoleKey.Enter:
                return password;
            case ConsoleKey.Backspace:
                if (password.Length > 0) 
                {
                    password = password.Substring(0, (password.Length - 1));
                    Console.Write("\b \b");
                }
                break;
            default:
                password += key.KeyChar;
                Console.Write("*");
                break;
        }
    }
}

2

(My) แพคเกจ nuget ทำเช่นนี้ขึ้นอยู่กับคำตอบด้านบน:

install-package PanoramicData.ConsoleExtensions

การใช้งาน:

using PanoramicData.ConsoleExtensions;

...

Console.Write("Password: ");
var password = ConsolePlus.ReadPassword();
Console.WriteLine();

URL โครงการ: https://github.com/panoramicdata/PanoramicData.ConsoleExtensions

ดึงคำขอต้อนรับ


ฉันใช้สิ่งนี้สำหรับโครงการขนาดเล็ก ทำงานได้ตามที่คาดหวัง ขอบคุณ
gmalenko

1

คุณสามารถผนวกคีย์ของคุณไปยังรายการที่เชื่อมโยงสะสม

เมื่อได้รับคีย์ Backspace ให้ลบคีย์สุดท้ายออกจากรายการ

เมื่อคุณได้รับรหัสป้อนให้ยุบรายการของคุณลงในสายอักขระและทำงานที่เหลือของคุณ


ฟังดูเป็นไปได้ แต่ฉันจะลบอักขระตัวสุดท้ายออกจากหน้าจอได้อย่างไร
Mohammad Nadeem

1

ฉันทำการเปลี่ยนแปลงบางอย่างสำหรับ Backspace

        string pass = "";
        Console.Write("Enter your password: ");
        ConsoleKeyInfo key;

        do
        {
            key = Console.ReadKey(true);

            // Backspace Should Not Work
            if (key.Key != ConsoleKey.Backspace)
            {
                pass += key.KeyChar;
                Console.Write("*");
            }
            else
            {
                pass = pass.Remove(pass.Length - 1);
                Console.Write("\b \b");
            }
        }
        // Stops Receving Keys Once Enter is Pressed
        while (key.Key != ConsoleKey.Enter);

        Console.WriteLine();
        Console.WriteLine("The Password You entered is : " + pass);

1

นี่คือรุ่นที่เรียบง่ายของฉัน ทุกครั้งที่คุณกดปุ่มให้ลบทั้งหมดจากคอนโซลและวาด '*' มากเท่าที่ความยาวของสตริงรหัสผ่านจะเป็น

int chr = 0;
string pass = "";
const int ENTER = 13;
const int BS = 8;

do
{
   chr = Console.ReadKey().KeyChar;
   Console.Clear(); //imediately clear the char you printed

   //if the char is not 'return' or 'backspace' add it to pass string
   if (chr != ENTER && chr != BS) pass += (char)chr;

   //if you hit backspace remove last char from pass string
   if (chr == BS) pass = pass.Remove(pass.Length-1, 1);

   for (int i = 0; i < pass.Length; i++)
   {
      Console.Write('*');
   }
} 
 while (chr != ENTER);

Console.Write("\n");
Console.Write(pass);

Console.Read(); //just to see the pass

0

ฉันได้อัปเดตเวอร์ชันของรอนนี่หลังจากใช้เวลานานเกินไปพยายามป้อนรหัสผ่านเพื่อค้นหาว่าฉันมี CAPS LOCK อยู่หรือไม่!

ด้วยรุ่นนี้สิ่งที่เคยเป็นข้อความ_CapsLockMessageจะ "ลอย" ในตอนท้ายของพื้นที่การพิมพ์และจะปรากฏเป็นสีแดง

รุ่นนี้ใช้รหัสอีกเล็กน้อยและต้องการการวนซ้ำแบบสำรวจ ในการใช้งาน CPU ของคอมพิวเตอร์ของฉันประมาณ 3% ถึง 4% แต่หนึ่งสามารถเพิ่มค่า Sleep () ขนาดเล็กเพื่อลดการใช้ CPU หากจำเป็น

    private const string _CapsLockMessage = " CAPS LOCK";

    /// <summary>
    /// Like System.Console.ReadLine(), only with a mask.
    /// </summary>
    /// <param name="mask">a <c>char</c> representing your choice of console mask</param>
    /// <returns>the string the user typed in</returns>
    public static string ReadLineMasked(char mask = '*')
    {
        // Taken from http://stackoverflow.com/a/19770778/486660
        var consoleLine = new StringBuilder();
        ConsoleKeyInfo keyInfo;
        bool isDone;
        bool isAlreadyLocked;
        bool isCapsLockOn;
        int cursorLeft;
        int cursorTop;
        ConsoleColor originalForegroundColor;

        isDone = false;
        isAlreadyLocked = Console.CapsLock;

        while (isDone == false)
        {
            isCapsLockOn = Console.CapsLock;
            if (isCapsLockOn != isAlreadyLocked)
            {
                if (isCapsLockOn)
                {
                    cursorLeft = Console.CursorLeft;
                    cursorTop = Console.CursorTop;
                    originalForegroundColor = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write("{0}", _CapsLockMessage);
                    Console.SetCursorPosition(cursorLeft, cursorTop);
                    Console.ForegroundColor = originalForegroundColor;
                }
                else
                {
                    cursorLeft = Console.CursorLeft;
                    cursorTop = Console.CursorTop;
                    Console.Write("{0}", string.Empty.PadRight(_CapsLockMessage.Length));
                    Console.SetCursorPosition(cursorLeft, cursorTop);
                }
                isAlreadyLocked = isCapsLockOn;
            }

            if (Console.KeyAvailable)
            {
                keyInfo = Console.ReadKey(intercept: true);

                if (keyInfo.Key == ConsoleKey.Enter)
                {
                    isDone = true;
                    continue;
                }

                if (!char.IsControl(keyInfo.KeyChar))
                {
                    consoleLine.Append(keyInfo.KeyChar);
                    Console.Write(mask);
                }
                else if (keyInfo.Key == ConsoleKey.Backspace && consoleLine.Length > 0)
                {
                    consoleLine.Remove(consoleLine.Length - 1, 1);

                    if (Console.CursorLeft == 0)
                    {
                        Console.SetCursorPosition(Console.BufferWidth - 1, Console.CursorTop - 1);
                        Console.Write(' ');
                        Console.SetCursorPosition(Console.BufferWidth - 1, Console.CursorTop - 1);
                    }
                    else
                    {
                        Console.Write("\b \b");
                    }
                }

                if (isCapsLockOn)
                {
                    cursorLeft = Console.CursorLeft;
                    cursorTop = Console.CursorTop;
                    originalForegroundColor = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write("{0}", _CapsLockMessage);
                    Console.CursorLeft = cursorLeft;
                    Console.CursorTop = cursorTop;
                    Console.ForegroundColor = originalForegroundColor;
                }
            }
        }

        Console.WriteLine();

        return consoleLine.ToString();
    }

-1

หากฉันเข้าใจอย่างถูกต้องคุณกำลังพยายามทำให้ backspace ลบทั้งอักขระ * ที่มองเห็นบนหน้าจอและอักขระแคชในตัวแปร pass ของคุณหรือไม่

ถ้าเป็นเช่นนั้นให้เปลี่ยนบล็อกอื่นเป็น:

            else
            {
                Console.Write("\b");
                pass = pass.Remove(pass.Length -1);
            }

1
สิ่งนี้จะทำงานได้ดียกเว้นว่าการลบอักขระโดย backspace จะไม่ปรากฏขึ้น
Mohammad Nadeem

-2
 string pass = "";
 Console.WriteLine("Enter your password: ");
 ConsoleKeyInfo key;

 do {
  key = Console.ReadKey(true);

  if (key.Key != ConsoleKey.Backspace) {
   pass += key.KeyChar;
   Console.Write("*");
  } else {
   Console.Write("\b \b");
   char[] pas = pass.ToCharArray();
   string temp = "";
   for (int i = 0; i < pass.Length - 1; i++) {
    temp += pas[i];
   }
   pass = temp;
  }
 }
 // Stops Receving Keys Once Enter is Pressed
 while (key.Key != ConsoleKey.Enter);

 Console.WriteLine();
 Console.WriteLine("The Password You entered is : " + pass);

1
คำตอบนี้ไม่ได้เพิ่มอะไรนอกเหนือจากคำตอบที่มีอยู่ นอกจากนี้คำตอบที่ดีควรอธิบายรหัสแทนการวางโค้ดลงในช่องคำตอบ โปรดอ่านวิธีการตอบ
durron597
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.