Ứng dụng bảng điều khiển mật khẩu


201

Tôi đã thử đoạn mã sau ...

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

Nhưng theo cách này, chức năng backspace không hoạt động trong khi gõ mật khẩu. Bất kì lời đề nghị nào?


11
Tôi đề nghị bạn không lặp lại bất cứ điều gì trở lại bàn điều khiển vì điều đó sẽ làm lộ độ dài của mật khẩu.
Ray Cheng

8
@RayCheng - đủ công bằng, nhưng rất ít giao diện người dùng (ngoài một số hệ thống Unix) không có gì cả. Để có trải nghiệm người dùng nhất quán với các ứng dụng và trang web khác, hiển thị ký tự * có lẽ là tốt nhất.
Stephen Holt

4
@StephenHolt Tôi khá chắc chắn mọi đầu vào mật khẩu dựa trên thiết bị đầu cuối mà tôi từng gặp đã chọn không lặp lại gì với thiết bị đầu cuối. Với các lợi ích bảo mật và thực tế rằng đây là một quy ước nổi tiếng trong thế giới Unix, cá nhân tôi nghĩ rằng tiếng vang không có gì là lựa chọn đúng đắn, trừ khi bạn tin rằng cơ sở người dùng của bạn có thể không quen với việc sử dụng thiết bị đầu cuối (trong trường hợp này Thay vào đó, tốt nhất là sử dụng GUI thay thế).
Ajedi32

Câu trả lời:


225

Console.Write("\b \b");sẽ xóa ký tự dấu hoa thị khỏi màn hình, nhưng bạn không có bất kỳ mã nào trong elsekhối loại bỏ ký tự đã nhập trước đó khỏi passbiến chuỗi của bạn .

Đây là mã làm việc có liên quan sẽ làm những gì bạn yêu cầu:

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
Oh tôi nghĩ \ b \ b sẽ đưa tôi trở lại hai nơi. Tuy nhiên, điều này dường như được làm việc hoàn hảo.
Mohammad Nadeem

8
@Nadeem: Lưu ý ký tự ' 'khoảng trắng ( ) giữa các ký tự backspace ( '\b'). "\b \b"đưa bạn trở lại một vị trí, sau đó in một khoảng trắng (sẽ đưa bạn một vị trí về phía trước) và sau đó đưa bạn trở lại một lần nữa, vì vậy bạn kết thúc nơi '*'ký tự bị xóa .
dtb

14
@Nadeem - Đầu tiên \bdi chuyển con trỏ trở lại một vị trí (bây giờ bên dưới *char cuối cùng . Ký [space]tự "in qua" dấu hoa thị, nhưng cũng di chuyển con trỏ một ký tự về phía trước một lần nữa, do đó, cuối cùng \bdi chuyển con trỏ trở lại nơi cuối cùng *được sử dụng được! (Phew - Hy vọng điều đó có ý nghĩa!)
CraigTP

3
if (pass.Length > 0)nên if (key.Key == ConsoleKey.Backspace && pass.Length > 0)nếu không bạn sẽ không nhận được ký tự cuối cùng của mật khẩu ..
MemphiZ

9
Nếu bạn không muốn người dùng có thể viết các ký tự điều khiển (như F5 hoặc Escape), bạn có thể thay thế if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter)bằng if (!char.IsControl(key.KeyChar)).
Safron

90

Đối với điều này, bạn nên sử dụng 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;
}

Điều này sẽ chỉ đưa tôi hai nơi trở lại. Nhưng điều tôi cần là khi tôi nhấn Backspace, ký tự cuối cùng sẽ bị xóa. Cũng giống như tính hợp lệ ban đầu của backspace.
Mohammad Nadeem

1
Tôi cần lồng if( pwd.Length > 0)vào câu lệnh khác đầu tiên để ngăn mọi người xóa câu hỏi :)
Chết. Sống

1
Tương tự như nhận xét của Safron về câu trả lời hiện được chấp nhận, elseđiều khoản cuối cùng sẽ được hưởng lợi từ một bài kiểm tra if (!char.IsControl(i.KeyChar))(hoặc ít nhất là if (i.KeyChar != '\u0000')).
Peter Taylor

1
Làm thế nào tôi có thể biến mật khẩu đó thành một chuỗi?
Joseph Kreifels II


47

Giải pháp hoàn chỉnh, vani C # .net 3.5+

Cắt dán :)

    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
Nó luôn luôn có thể khó khăn hơn :) Không hoạt động trên Mac / Linux vì dòng mới không được công nhận. Môi trường.NewLine có chuỗi cho một dòng mới. Vì vậy, tôi đã sửa đổi điều này thành: while (! Môi trường.NewLine.Contains (chr = System.Console.ReadKey (true) .KeyChar))
Hugo Logmans 17/07/18

19

Lấy câu trả lời hàng đầu, cũng như các đề xuất từ ​​nhận xét của mình và sửa đổi nó để sử dụng SecureString thay vì String, kiểm tra tất cả các phím điều khiển và không lỗi hoặc viết thêm "*" lên màn hình khi độ dài mật khẩu bằng 0, giải pháp của tôi là:

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

Mine bỏ qua các ký tự điều khiển và xử lý gói dòng:

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

Hoạt động hoàn hảo. Bạn có thể phải thêm mã để làm cho DELETE ký tự xóa tất cả văn bản đã nhập. Chuỗi khóa của nó là CTRL + BACKSPACEvà mã char của nó là 0x7f.
Alex Essilfie

9

Đọc đầu vào bảng điều khiển khó, bạn cần xử lý các phím đặc biệt như Ctrl, Alt, cũng như phím con trỏ và Xóa lùi / Xóa. Trên một số bố cục bàn phím, như Ctrl Thụy Điển thậm chí còn cần thiết để nhập các phím tồn tại trực tiếp trên bàn phím Hoa Kỳ. Tôi tin rằng cố gắng xử lý việc này bằng cách sử dụng "cấp thấp"Console.ReadKey(true) là rất khó, vì vậy cách dễ nhất và mạnh mẽ nhất là chỉ vô hiệu hóa "tiếng vang đầu vào của bàn điều khiển" trong khi nhập mật khẩu bằng một chút WINAPI.

Mẫu dưới đây dựa trên câu trả lời Đọc mật khẩu từ câu hỏi std :: 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

Điều này che dấu mật khẩu bằng một hình vuông màu đỏ, sau đó trở lại màu ban đầu sau khi mật khẩu đã được nhập.

Nó không ngăn người dùng sử dụng bản sao / dán để lấy mật khẩu, nhưng nếu nó chỉ dừng lại ở việc ai đó nhìn qua vai bạn thì đây là một giải pháp nhanh chóng tốt.

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;

Vấn đề duy nhất là nếu bạn thực hiện backspace nền mà bạn có các ký tự vẫn màu đỏ. Tôi thà đi với cài đặt ForegroundColor là origBG để có mật khẩu nhập kiểu Linux.
mababin

1
Bạn cũng có thể làm Console.CursorVisible=falsevà đặt nó trở lại giá trị trước đó. Điều này sẽ ngăn ai đó đạt đỉnh ở độ dài mật khẩu.
mababin

6

Tôi đã tìm thấy một lỗi trong giải pháp vanilla C # 3.5 .NET của shermy mà không có tác dụng gì. Tôi cũng đã kết hợp Damian Leszczyński - ý tưởng SecureString của Vash ở đây nhưng bạn có thể sử dụng một chuỗi thông thường nếu bạn thích.

L BUI: Nếu bạn nhấn backspace trong dấu nhắc mật khẩu và độ dài hiện tại của mật khẩu là 0 thì dấu hoa thị được chèn không chính xác trong mặt nạ mật khẩu. Để sửa lỗi này sửa đổi phương pháp sau.

    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

Đây là phiên bản bổ sung hỗ trợ cho Escapekhóa (trả về nullchuỗi)

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) gói nuget để làm điều này, dựa trên câu trả lời hàng đầu:

install-package PanoramicData.ConsoleExtensions

Sử dụng:

using PanoramicData.ConsoleExtensions;

...

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

URL dự án: https://github.com/panoramicdata/PanoramicData.ConsoleExtensions

Kéo yêu cầu chào mừng.


Tôi đã sử dụng điều này cho một dự án nhỏ. Làm việc như mong đợi. Cảm ơn bạn
gmalenko

1

Bạn có thể nối các khóa của mình vào danh sách liên kết tích lũy.

Khi nhận được một phím backspace, hãy xóa khóa cuối cùng khỏi danh sách.

Khi bạn nhận được khóa enter, thu gọn danh sách của bạn thành một chuỗi và thực hiện phần còn lại của công việc.


Âm thanh có thể đạt được nhưng làm thế nào tôi sẽ loại bỏ ký tự cuối cùng khỏi màn hình.
Mohammad Nadeem

1

Tôi đã thực hiện một số thay đổi cho 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

Đây là phiên bản đơn giản của tôi. Mỗi lần bạn nhấn một phím, hãy xóa tất cả khỏi bảng điều khiển và rút ra nhiều '*' như độ dài của chuỗi mật khẩu.

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

Tôi đã cập nhật phiên bản của Ronnie sau khi dành quá nhiều thời gian cố gắng nhập mật khẩu chỉ để biết rằng tôi đã bật CAPS LOCK!

Với phiên bản này, thông báo _CapsLockMessagesẽ xuất hiện ở cuối khu vực gõ và sẽ được hiển thị màu đỏ.

Phiên bản này cần thêm một chút mã và không yêu cầu vòng bỏ phiếu. Trên CPU máy tính của tôi sử dụng khoảng 3% đến 4%, nhưng người ta luôn có thể thêm một giá trị Ngủ () nhỏ để giảm mức sử dụng CPU nếu cần.

    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

Nếu tôi hiểu điều này một cách chính xác, bạn đang cố gắng làm cho backspace xóa cả ký tự * hiển thị trên màn hình và ký tự được lưu trong bộ đệm của bạn?

Nếu vậy, sau đó chỉ cần thay đổi khối khác của bạn thành này:

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

1
Điều này sẽ hoạt động tốt, ngoại trừ việc xóa ký tự bằng backspace sẽ không được hiển thị.
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
Câu trả lời này không thêm bất cứ điều gì ngoài những câu trả lời hiện có. Ngoài ra, câu trả lời tốt thường giải thích mã, thay vì chỉ dán mã vào hộp trả lời. Vui lòng đọc Cách trả lời
durron597
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.