c# - পাসওয়ার্ড মাস্কিং কনসোল অ্যাপ্লিকেশন




passwords console-application (10)

আমি নিম্নলিখিত কোড চেষ্টা করেছিলাম ...

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

কিন্তু এই ভাবে ব্যাকস্পেস কার্যকারিতা পাসওয়ার্ড টাইপ করার সময় কাজ করে না। যেকোনো পরামর্শ?


আপনি একটি সংযোজিত লিঙ্ক তালিকা আপনার কী যুক্ত করতে পারে।

যখন একটি ব্যাকস্পেস কী প্রাপ্ত হয়, তালিকার শেষ কীটি সরিয়ে ফেলুন।

যখন আপনি এন্টার কী পাবেন, একটি স্ট্রিংয়ের মধ্যে আপনার তালিকাটি ভেঙ্গে ফেলুন এবং আপনার বাকি কাজটি করুন।


আমি আমার CAPS লক চালু ছিল এটি জানতে শুধুমাত্র পাসওয়ার্ড প্রবেশ করার চেষ্টা করার সময় অতিবাহিত করার পরে রনি এর সংস্করণ আপডেট করেছি!

এই সংস্করণটি কি কখনও _CapsLockMessage এ বার্তাটি টাইপিংয়ের শেষে "float" করবে এবং লাল প্রদর্শিত হবে।

এই সংস্করণটি একটু বেশি কোড নেয় এবং একটি পোলিং লুপ প্রয়োজন। আমার কম্পিউটারে CPU ব্যবহার প্রায় 3% থেকে 4%, কিন্তু প্রয়োজনে সিপিইউ ব্যবহার হ্রাস করার জন্য সর্বদা একটি ছোট ঘুম () মান যোগ করতে পারে।

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

আমি শেরেমির ভ্যানিলা সি # 3.5 3.5 নেট সমাধানটিতে একটি বাগ খুঁজে পেয়েছি যা অন্যথায় একটি কবজ কাজ করে। আমি ড্যামিয়ান লেসজকিনস্কিকেও অন্তর্ভুক্ত করেছি - ভ্যাশের সিকিউরিং আইডিয়া এখানে কিন্তু আপনি যদি পছন্দ করেন তবে আপনি সাধারণ স্ট্রিং ব্যবহার করতে পারেন।

BUG: পাসওয়ার্ড প্রম্পট চলাকালীন আপনি ব্যাকস্পেসটি চাপলে এবং পাসওয়ার্ডটির বর্তমান দৈর্ঘ্য 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;
    }

উপরের উত্তরটি গ্রহণের পাশাপাশি এর মন্তব্যগুলি থেকে পরামর্শগুলি এবং স্ট্রিংয়ের পরিবর্তে সিকিউরিং ব্যবহার করার জন্য এটি সংশোধন করা, সকল নিয়ন্ত্রণ কীগুলির জন্য পরীক্ষা করা, এবং পাসওয়ার্ডের দৈর্ঘ্য 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;
}

এখানে একটি সংস্করণ যা 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:
                password = password.Substring(0, (password.Length - 1));
                Console.Write("\b \b");
                break;
            default:
                password += key.KeyChar;
                Console.Write("*");
                break;
        }
    }
}

এটি একটি লাল বর্গক্ষেত্রের পাসওয়ার্ডটি মাস্ক করে, তারপর পাসওয়ার্ডটি প্রবেশ করার পরে মূল রঙগুলিতে ফিরে যায়।

এটি ব্যবহারকারীকে পাসওয়ার্ড পেতে কপি / পেস্ট ব্যবহার করতে বাধা দেয় না, তবে এটি যদি আপনার কাঁধের দিকে তাকিয়ে থাকে তবে এটি একটি ভাল দ্রুত সমাধান।

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;

কনসোল ইনপুট পড়া কঠিন, আপনাকে Ctrl, Alt, কার্সার কী এবং ব্যাকস্পেস / মুছে ফেলার মতো বিশেষ কীগুলি পরিচালনা করতে হবে। কিছু কীবোর্ড লেআউটগুলিতে, Swedish Ctrl এর মতোই সরাসরি কীবোর্ড কীবোর্ডে থাকা কীগুলি প্রবেশ করতে প্রয়োজন। আমি বিশ্বাস করি যে "নিম্ন স্তরের" কনসোল ব্যবহার করে এটি পরিচালনা করার চেষ্টা করা হচ্ছে। Console.ReadKey(true) খুব কঠিন, তাই সহজ এবং সবচেয়ে শক্তিশালী উপায়টি কেবল "কনসোল ইনপুট প্রতিধ্বনি" নিষ্ক্রিয় করার জন্য কিছুটা উইনপিআই ব্যবহার করে পাসওয়ার্ড প্রবেশ করার সময় ।

নীচের নমুনা 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;
    }

খনি নিয়ন্ত্রণ অক্ষর উপেক্ষা এবং লাইন মোড়ানো হ্যান্ডলগুলি:

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

সম্পূর্ণ সমাধান, ভ্যানিলা সি # .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('*');
            }
        }
    }

Console.Write("\b \b"); পর্দা থেকে তারকাচিহ্ন চরিত্র মুছে ফেলবে, তবে আপনার else ব্লকের মধ্যে কোনও কোড 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);




masking