Tạo mật khẩu ngẫu nhiên


229

Khi một người dùng trên trang web của chúng tôi mất mật khẩu và truy cập trang Mất mật khẩu, chúng tôi cần cung cấp cho anh ta mật khẩu tạm thời mới. Tôi thực sự không quan tâm đến việc nó ngẫu nhiên như thế nào, hoặc nếu nó phù hợp với tất cả các quy tắc mật khẩu mạnh "cần thiết", tất cả những gì tôi muốn làm là cung cấp cho họ mật khẩu mà họ có thể thay đổi sau này.

Ứng dụng này là một ứng dụng Web được viết bằng C #. Vì vậy, tôi đã nghĩ đến việc có ý nghĩa và đi theo con đường dễ dàng sử dụng một phần của Hướng dẫn. I E

Guid.NewGuid().ToString("d").Substring(1,8)

Suggesstions? suy nghĩ?


12
Một vài giải pháp tốt ở đây, nhưng một lời khuyên nhỏ: Đừng tạo mật khẩu chứa bất kỳ ký tự nào trong số này: Oo0Ili (bạn hiểu tại sao) :)
stian.net

2
Tôi đã thêm một câu trả lời sử dụng KeePass làm trình tạo mật khẩu và trong số nhiều tùy chọn được đưa ra, tôi cũng đưa vào tùy chọn để loại trừ các ký tự trông giống nhau, như được đề cập bởi @ stian.net.
Peter

Câu trả lời:


570

7
Không biết rằng Framework có một phương pháp như vậy! Tuyệt vời! Sẽ trao đổi mã hiện tại của tôi cho điều này!
FryHard

35
Tôi đã tìm thấy nó sau khi dành gần một ngày để hoàn thiện mã gen pw của riêng tôi. Hình ảnh tôi cảm thấy như thế nào;)
Rik

16
AFAIK phương pháp này không tạo ra mật khẩu tuân theo chính sách mật khẩu trên tên miền nên không phù hợp với mọi cách sử dụng.
teebot

19
Vấn đề chính với giải pháp này là bạn không thể kiểm soát bộ ký tự, do đó bạn không thể loại bỏ các ký tự mơ hồ trực quan (0oOl1i! |) Có thể thực sự quan trọng trong thực tế.
David Hammond

20
Bất cứ điều gì cho ASP.NET Core?
shashwat

114
public string CreatePassword(int length)
{
        const string valid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        StringBuilder res = new StringBuilder();
        Random rnd = new Random();
        while (0 < length--)
        {
            res.Append(valid[rnd.Next(valid.Length)]);
        }
        return res.ToString();
}

Điều này có một lợi ích tốt là có thể chọn từ danh sách các ký tự có sẵn cho mật khẩu được tạo (ví dụ: chỉ chữ số, chỉ chữ hoa hoặc chỉ chữ thường, v.v.)


2
phương pháp này (cơ sở 62) vượt trội hơn GUID (cơ sở 16) về độ mạnh: chuỗi hex 8 ký tự tương đương với chuỗi 4-5 ký tự chữ số
Jimmy

57
Randomkhông bảo mật bằng mật mã; System.Security.Cryptography.RNGCryptoServiceProviderlà một lựa chọn tốt hơn.
anaximander

3
Điều này sẽ tạo cùng một mật khẩu mỗi lần phương thức được gọi, vì lớp Random được khởi tạo mỗi lần. Điều này có thể được thực hiện an toàn bằng cách di chuyển Ngẫu nhiên ra khỏi phương thức này và sử dụng lại thể hiện.
Jon

6
Không, nó sẽ không. Trừ khi hai người quyết định thay đổi mật khẩu cùng một lúc.
Radu094

10
trích dẫn từ câu hỏi: đừng quan tâm "nếu nó phù hợp với tất cả các quy tắc mật khẩu mạnh" cần thiết "... cảm ơn vì đã hạ thấp câu trả lời này
Radu094

35

Các mục tiêu chính của mã của tôi là:

  1. Sự phân bố chuỗi gần như thống nhất (không quan tâm đến những sai lệch nhỏ, miễn là chúng nhỏ)
  2. Nó xuất ra hơn một vài tỷ chuỗi cho mỗi bộ đối số. Tạo một chuỗi 8 ký tự (~ 47 bit entropy) là vô nghĩa nếu PRNG của bạn chỉ tạo ra 2 tỷ (31 bit của entropy) các giá trị khác nhau.
  3. Nó an toàn, vì tôi mong mọi người sử dụng mật khẩu này hoặc mật khẩu bảo mật khác.

Thuộc tính đầu tiên đạt được bằng cách lấy modulo giá trị 64 bit kích thước bảng chữ cái. Đối với các bảng chữ cái nhỏ (chẳng hạn như 62 ký tự trong câu hỏi), điều này dẫn đến sai lệch không đáng kể. Tài sản thứ hai và thứ ba đạt được bằng cách sử dụng RNGCryptoServiceProviderthay vì System.Random.

using System;
using System.Security.Cryptography;

public static string GetRandomAlphanumericString(int length)
{
    const string alphanumericCharacters =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
        "abcdefghijklmnopqrstuvwxyz" +
        "0123456789";
    return GetRandomString(length, alphanumericCharacters);
}

public static string GetRandomString(int length, IEnumerable<char> characterSet)
{
    if (length < 0)
        throw new ArgumentException("length must not be negative", "length");
    if (length > int.MaxValue / 8) // 250 million chars ought to be enough for anybody
        throw new ArgumentException("length is too big", "length");
    if (characterSet == null)
        throw new ArgumentNullException("characterSet");
    var characterArray = characterSet.Distinct().ToArray();
    if (characterArray.Length == 0)
        throw new ArgumentException("characterSet must not be empty", "characterSet");

    var bytes = new byte[length * 8];
    new RNGCryptoServiceProvider().GetBytes(bytes);
    var result = new char[length];
    for (int i = 0; i < length; i++)
    {
        ulong value = BitConverter.ToUInt64(bytes, i * 8);
        result[i] = characterArray[value % (uint)characterArray.Length];
    }
    return new string(result);
}

(Đây là bản sao câu trả lời của tôi về Làm cách nào tôi có thể tạo ngẫu nhiên 8 ký tự, chuỗi ký tự chữ và số trong C #? )


1
Nếu UInt64.MaxValue không chia hết cho nhân vậtArray.Lipse thì các ký tự được chọn ngẫu nhiên sẽ không được phân bổ đều (mặc dù điều này sẽ chỉ là một hiệu ứng rất nhỏ).
Kiểm lâm viên Jeff Walker Code

1
@JeffWalkerCodeRanger Đó là lý do tại sao tôi nói thiên vị không đáng kể, không phải không thiên vị. Ngay cả với một petabyte đầu ra, bạn có ít hơn 1% để phân biệt điều này với một trình tạo chuỗi hoàn toàn không thiên vị. Sự phức tạp bổ sung của không thiên vị hoàn hảo rõ ràng là không xứng đáng với lợi ích khá lý thuyết trong tính ngẫu nhiên ở đây.
CodeInChaos

9
Đối với những người sử dụng .NET Core, thay thế "RNGCryptoServiceProvider (). GetBytes (byte);" với "System.Security.Cryptography.RandomNumberGenerator.Create (). GetBytes (byte);"
NPNelson

24
public string GenerateToken(int length)
{
    using (RNGCryptoServiceProvider cryptRNG = new RNGCryptoServiceProvider())
    {
        byte[] tokenBuffer = new byte[length];
        cryptRNG.GetBytes(tokenBuffer);
        return Convert.ToBase64String(tokenBuffer);
    }
}

(Bạn cũng có thể có lớp mà phương thức này thực hiện IDis Dùng một lần, giữ một tham chiếu đến RNGCryptoServiceProvidervà loại bỏ nó đúng cách, để tránh lặp lại nó ngay lập tức.)

Điều lưu ý là vì điều này trả về một chuỗi cơ sở 64, độ dài đầu ra luôn là bội số của 4, với không gian thừa sử dụng =làm ký tự đệm. Các lengththam số xác định độ dài của bộ đệm byte, không phải là chuỗi đầu ra (và do đó có lẽ không phải là tên tốt nhất cho tham số đó, bây giờ tôi nghĩ về nó). Điều này kiểm soát bao nhiêu byte entropy mật khẩu sẽ có. Tuy nhiên, vì cơ sở 64 sử dụng khối 4 ký tự để mã hóa cho mỗi 3 byte đầu vào, nếu bạn yêu cầu độ dài không phải là bội số của 3, sẽ có thêm một "khoảng trắng" và nó sẽ sử dụng =để điền vào thêm.

Nếu bạn không thích sử dụng chuỗi cơ sở 64 vì bất kỳ lý do gì, bạn có thể thay thế Convert.ToBase64String()cuộc gọi bằng chuyển đổi thành chuỗi thông thường hoặc bằng bất kỳ Encodingphương thức nào; ví dụ. Encoding.UTF8.GetString(tokenBuffer)- chỉ cần đảm bảo bạn chọn một bộ ký tự có thể biểu thị đầy đủ các giá trị ra khỏi RNG và tạo ra các ký tự tương thích với bất cứ nơi nào bạn gửi hoặc lưu trữ này. Sử dụng Unicode, ví dụ, có xu hướng cung cấp rất nhiều ký tự Trung Quốc. Sử dụng cơ sở-64 đảm bảo một bộ ký tự tương thích rộng rãi và các đặc điểm của chuỗi như vậy không làm cho nó kém an toàn hơn miễn là bạn sử dụng thuật toán băm tốt.


Tôi nghĩ bạn có nghĩa là đặt tokenBuffer nơi bạn có linkBuf.
PIntag

Khi tôi sử dụng mã này và vượt qua độ dài 10, chuỗi trả về luôn dài 16 ký tự và 2 ký tự cuối cùng luôn luôn là "==". Tôi đang sử dụng nó không đúng? Là độ dài quy định trong hex?
PIntag

1
Độ dài được chỉ định là số byte ngẫu nhiên (hoặc "entropy", như đã biết về mặt kỹ thuật). Tuy nhiên, giá trị được trả về là mã hóa cơ sở 64, có nghĩa là do cách mã hóa cơ sở 64 hoạt động, độ dài đầu ra luôn là bội số của 4. Đôi khi, đó là nhiều ký tự hơn mức cần mã hóa tất cả các ký tự, vì vậy nó sử dụng = ký tự để loại bỏ phần còn lại.
anaximander

1
RNGCryptoServiceProvider là một IDis Dùng một lần, vì vậy tôi sẽ triển khai nó với mẫu sử dụng (tức là sử dụng (var cryptRNG = new RNGCryptoServiceProvider ()) {...})
kloarubeek

@kloarubeek Một điểm hợp lệ, và một gợi ý hay. Tôi đã thêm nó vào mẫu mã của tôi.
anaximander

20

Cái này lớn hơn rất nhiều, nhưng tôi nghĩ nó có vẻ toàn diện hơn một chút: http://www.obviex.com/Samples/Password.aspx

///////////////////////////////////////////////////////////////////////////////
// SAMPLE: Generates random password, which complies with the strong password
//         rules and does not contain ambiguous characters.
//
// To run this sample, create a new Visual C# project using the Console
// Application template and replace the contents of the Class1.cs file with
// the code below.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// 
// Copyright (C) 2004 Obviex(TM). All rights reserved.
// 
using System;
using System.Security.Cryptography;

/// <summary>
/// This class can generate random passwords, which do not include ambiguous 
/// characters, such as I, l, and 1. The generated password will be made of
/// 7-bit ASCII symbols. Every four characters will include one lower case
/// character, one upper case character, one number, and one special symbol
/// (such as '%') in a random order. The password will always start with an
/// alpha-numeric character; it will not start with a special symbol (we do
/// this because some back-end systems do not like certain special
/// characters in the first position).
/// </summary>
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_UCASE  = "ABCDEFGHJKLMNPQRSTWXYZ";
    private static string PASSWORD_CHARS_NUMERIC= "23456789";
    private static string PASSWORD_CHARS_SPECIAL= "*$-+?_&=!%{}/";

    /// <summary>
    /// Generates a random password.
    /// </summary>
    /// <returns>
    /// Randomly generated password.
    /// </returns>
    /// <remarks>
    /// The length of the generated password will be determined at
    /// random. It will be no shorter than the minimum default and
    /// no longer than maximum default.
    /// </remarks>
    public static string Generate()
    {
        return Generate(DEFAULT_MIN_PASSWORD_LENGTH, 
                        DEFAULT_MAX_PASSWORD_LENGTH);
    }

    /// <summary>
    /// Generates a random password of the exact length.
    /// </summary>
    /// <param name="length">
    /// Exact password length.
    /// </param>
    /// <returns>
    /// Randomly generated password.
    /// </returns>
    public static string Generate(int length)
    {
        return Generate(length, length);
    }

    /// <summary>
    /// Generates a random password.
    /// </summary>
    /// <param name="minLength">
    /// Minimum password length.
    /// </param>
    /// <param name="maxLength">
    /// Maximum password length.
    /// </param>
    /// <returns>
    /// Randomly generated password.
    /// </returns>
    /// <remarks>
    /// The length of the generated password will be determined at
    /// random and it will fall with the range determined by the
    /// function parameters.
    /// </remarks>
    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[][] 
        {
            PASSWORD_CHARS_LCASE.ToCharArray(),
            PASSWORD_CHARS_UCASE.ToCharArray(),
            PASSWORD_CHARS_NUMERIC.ToCharArray(),
            PASSWORD_CHARS_SPECIAL.ToCharArray()
        };

        // 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.
        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
        rng.GetBytes(randomBytes);

        // 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)];
        else
            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;
            else
                nextLeftGroupsOrderIdx = random.Next(0, 
                                                     lastLeftGroupsOrderIdx);

            // 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;
            else
                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] = 
                                          charGroups[nextGroupIdx].Length;
            // There are more unprocessed characters left.
            else
            {
                // 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];
                    charGroups[nextGroupIdx][nextCharIdx] = temp;
                }
                // Decrement the number of unprocessed characters in
                // this group.
                charsLeftInGroup[nextGroupIdx]--;
            }

            // If we processed the last group, start all over.
            if (lastLeftGroupsOrderIdx == 0)
                lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
            // There are more unprocessed groups left.
            else
            {
                // 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];
                    leftGroupsOrder[nextLeftGroupsOrderIdx] = temp;
                }
                // Decrement the number of unprocessed groups.
                lastLeftGroupsOrderIdx--;
            }
        }

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

/// <summary>
/// Illustrates the use of the RandomPassword class.
/// </summary>
public class RandomPasswordTest
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // Print 100 randomly generated passwords (8-to-10 char long).
        for (int i=0; i<100; i++)
            Console.WriteLine(RandomPassword.Generate(8, 10));
    }
}
//
// END OF FILE
///////////////////////////////////////////////////////////////////////////////

2
Nó chỉ ra rằng có sự hỗ trợ cho điều này bởi khuôn khổ. Vì vậy, tôi chấp nhận câu trả lời đó hơn!
FryHard

1
Chỉ tạo 2 ^ 31 mật khẩu khác nhau, ngay cả với kích thước đầu ra dài, là một chút ở phía thấp. Có thể đủ để chống lại các cuộc tấn công trực tuyến, nhưng chắc chắn là nhỏ đối với các cuộc tấn công ngoại tuyến. => Tôi sẽ không đề xuất điều này.
CodeInChaos

Đây vẫn là một câu trả lời tốt vì hỗ trợ "tích hợp" thực sự là Tư cách thành viên, và nếu bạn quyết định không sử dụng Thành viên ASP.NET thì sao? Nó vẫn hoạt động, vì phần phụ thuộc là System.Web.dll, nhưng hơi khó xử vì phương thức này không được bao gồm. @GEOCHET: Cảm ơn bạn đã đăng bài thay thế này.
Chris Gomez

8

Tôi biết rằng đây là một chủ đề cũ, nhưng tôi có những gì có thể là một giải pháp khá đơn giản cho ai đó sử dụng. Dễ thực hiện, dễ hiểu và dễ xác nhận.

Xem xét các yêu cầu sau:

Tôi cần một mật khẩu ngẫu nhiên được tạo trong đó có ít nhất 2 chữ cái viết thường, 2 chữ cái viết hoa và 2 số. Mật khẩu cũng phải có độ dài tối thiểu 8 ký tự.

Biểu thức chính quy sau đây có thể xác nhận trường hợp này:

^(?=\b\w*[a-z].*[a-z]\w*\b)(?=\b\w*[A-Z].*[A-Z]\w*\b)(?=\b\w*[0-9].*[0-9]\w*\b)[a-zA-Z0-9]{8,}$

Nó nằm ngoài phạm vi của câu hỏi này - nhưng regex dựa trên lookahead / lookbehindlookaround .

Đoạn mã sau sẽ tạo một bộ ký tự ngẫu nhiên phù hợp với yêu cầu này:

public static string GeneratePassword(int lowercase, int uppercase, int numerics) {
    string lowers = "abcdefghijklmnopqrstuvwxyz";
    string uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string number = "0123456789";

    Random random = new Random();

    string generated = "!";
    for (int i = 1; i <= lowercase; i++)
        generated = generated.Insert(
            random.Next(generated.Length), 
            lowers[random.Next(lowers.Length - 1)].ToString()
        );

    for (int i = 1; i <= uppercase; i++)
        generated = generated.Insert(
            random.Next(generated.Length), 
            uppers[random.Next(uppers.Length - 1)].ToString()
        );

    for (int i = 1; i <= numerics; i++)
        generated = generated.Insert(
            random.Next(generated.Length), 
            number[random.Next(number.Length - 1)].ToString()
        );

    return generated.Replace("!", string.Empty);

}

Để đáp ứng yêu cầu trên, chỉ cần gọi như sau:

String randomPassword = GeneratePassword(3, 3, 3);

Mã bắt đầu bằng một ký tự không hợp lệ ( "!") - để chuỗi có độ dài mà các ký tự mới có thể được chèn vào.

Sau đó, nó lặp từ 1 đến # ký tự chữ thường, và trên mỗi lần lặp, lấy một mục ngẫu nhiên từ danh sách chữ thường và đưa nó vào một vị trí ngẫu nhiên trong chuỗi.

Sau đó, nó lặp lại vòng lặp cho chữ in hoa và cho số.

Điều này cung cấp cho bạn các chuỗi có độ dài = lowercase + uppercase + numericsvào đó các ký tự chữ thường, chữ hoa và số của số bạn muốn được đặt theo thứ tự ngẫu nhiên.


3
Đừng sử dụng System.Randomcho những thứ quan trọng về bảo mật như mật khẩu. Sử dụngRNGCryptoServiceProvider
CodeInChaos

lowers[random.Next(lowers.Length - 1)].ToString() Mã này sẽ không bao giờ tạo ra một 'z'. Random.Next tạo ra các số nguyên nhỏ hơn số lượng được cung cấp, vì vậy bạn không nên trừ đi số nguyên đó từ độ dài.
notbono

6

Đối với loại mật khẩu này, tôi có xu hướng sử dụng một hệ thống có khả năng tạo mật khẩu "được sử dụng" dễ dàng hơn. Ngắn, thường được tạo thành từ các mảnh có thể phát âm và một vài số, và không có sự mơ hồ giữa các vi khuẩn (đó là 0 hoặc O? A 1 hay I?). Cái gì đó như

string[] words = { 'bur', 'ler', 'meh', 'ree' };
string word = "";

Random rnd = new Random();
for (i = 0; i < 3; i++)
   word += words[rnd.Next(words.length)]

int numbCount = rnd.Next(4);
for (i = 0; i < numbCount; i++)
  word += (2 + rnd.Next(7)).ToString();

return word;

(Nhập ngay vào trình duyệt, vì vậy chỉ sử dụng làm hướng dẫn. Ngoài ra, hãy thêm nhiều từ hơn).


6

Tôi không thích mật khẩu mà Memberhip.GeneratePassword () tạo ra, vì chúng quá xấu và có quá nhiều ký tự đặc biệt.

Mã này tạo ra một mật khẩu 10 chữ số không quá xấu.

string password = Guid.NewGuid().ToString("N").ToLower()
                      .Replace("1", "").Replace("o", "").Replace("0","")
                      .Substring(0,10);

Chắc chắn, tôi có thể sử dụng Regex để thực hiện tất cả các thay thế nhưng đây là IMO dễ đọc và dễ bảo trì hơn.


2
GUID không nên bị lạm dụng dưới dạng tiền điện tử PRNG
CodeInChaos

3
Nếu bạn sẽ sử dụng phương pháp này, bạn có thể sử dụng .ToString ("N") và bạn sẽ không phải thay thế "-". Cũng không cần phải thay thế "l", vì nó không phải là một chữ số hex.
JackAce 17/03/2016

Hoàn toàn thấy lý do tại sao bạn làm điều này. Tôi chỉ cần một mật khẩu tồn tại ngắn (dưới một ngày) mà không phải quá độc đáo cho mỗi người dùng. Yanking những người và số không là một cách tuyệt vời để giảm sự nhầm lẫn. Tôi cũng chỉ chuyển tôi sang chữ hoa và sau đó cắt độ dài xuống còn 6. Giống như gợi ý 'N'. Cảm ơn!
Hóa đơn Noel

6

Tôi đã tạo lớp này sử dụng RNGCryptoServiceProvider và nó rất linh hoạt. Thí dụ:

var generator = new PasswordGenerator(minimumLengthPassword: 8,
                                      maximumLengthPassword: 15,
                                      minimumUpperCaseChars: 2,
                                      minimumNumericChars: 3,
                                      minimumSpecialChars: 2);
string password = generator.Generate();

Đó là tuyệt vời, giấy phép trên lớp đó là gì? Tôi có thể sử dụng nó?
codeulike

Sử dụng nó như bạn muốn!
Alex Siepman

3

Tôi đã tạo phương thức này tương tự như có sẵn trong nhà cung cấp thành viên. Điều này hữu ích nếu bạn không muốn thêm tham chiếu web trong một số ứng dụng.

Nó hoạt động rất tốt.

public static string GeneratePassword(int Length, int NonAlphaNumericChars)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        string allowedNonAlphaNum = "!@#$%^&*()_-+=[{]};:<>|./?";
        Random rd = new Random();

        if (NonAlphaNumericChars > Length || Length <= 0 || NonAlphaNumericChars < 0)
            throw new ArgumentOutOfRangeException();

            char[] pass = new char[Length];
            int[] pos = new int[Length];
            int i = 0, j = 0, temp = 0;
            bool flag = false;

            //Random the position values of the pos array for the string Pass
            while (i < Length - 1)
            {
                j = 0;
                flag = false;
                temp = rd.Next(0, Length);
                for (j = 0; j < Length; j++)
                    if (temp == pos[j])
                    {
                        flag = true;
                        j = Length;
                    }

                if (!flag)
                {
                    pos[i] = temp;
                    i++;
                }
            }

            //Random the AlphaNumericChars
            for (i = 0; i < Length - NonAlphaNumericChars; i++)
                pass[i] = allowedChars[rd.Next(0, allowedChars.Length)];

            //Random the NonAlphaNumericChars
            for (i = Length - NonAlphaNumericChars; i < Length; i++)
                pass[i] = allowedNonAlphaNum[rd.Next(0, allowedNonAlphaNum.Length)];

            //Set the sorted array values by the pos array for the rigth posistion
            char[] sorted = new char[Length];
            for (i = 0; i < Length; i++)
                sorted[i] = pass[pos[i]];

            string Pass = new String(sorted);

            return Pass;
    }

6
Đừng sử dụng System.Randomcho những thứ quan trọng về bảo mật như mật khẩu. Sử dụngRNGCryptoServiceProvider
CodeInChaos

3

Tôi luôn rất hài lòng với trình tạo mật khẩu tích hợp trong KeePass. Vì KeePass là một chương trình .Net và nguồn mở, tôi đã quyết định đào xung quanh mã một chút. Tôi đã kết thúc việc giới thiệu KeePass.exe, bản sao được cung cấp trong bản cài đặt ứng dụng tiêu chuẩn, như một tài liệu tham khảo trong dự án của tôi và viết mã dưới đây. Bạn có thể thấy nó linh hoạt như thế nào nhờ KeePass. Bạn có thể chỉ định độ dài, bao gồm các ký tự / không bao gồm, v.v ...

using KeePassLib.Cryptography.PasswordGenerator;
using KeePassLib.Security;


public static string GeneratePassword(int passwordLength, bool lowerCase, bool upperCase, bool digits,
        bool punctuation, bool brackets, bool specialAscii, bool excludeLookAlike)
    {
        var ps = new ProtectedString();
        var profile = new PwProfile();
        profile.CharSet = new PwCharSet();
        profile.CharSet.Clear();

        if (lowerCase)
            profile.CharSet.AddCharSet('l');
        if(upperCase)
            profile.CharSet.AddCharSet('u');
        if(digits)
            profile.CharSet.AddCharSet('d');
        if (punctuation)
            profile.CharSet.AddCharSet('p');
        if (brackets)
            profile.CharSet.AddCharSet('b');
        if (specialAscii)
            profile.CharSet.AddCharSet('s');

        profile.ExcludeLookAlike = excludeLookAlike;
        profile.Length = (uint)passwordLength;
        profile.NoRepeatingCharacters = true;

        KeePassLib.Cryptography.PasswordGenerator.PwGenerator.Generate(out ps, profile, null, _pool);

        return ps.ReadString();
    }

2
public static string GeneratePassword(int passLength) {
        var chars = "abcdefghijklmnopqrstuvwxyz@#$&ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        var random = new Random();
        var result = new string(
            Enumerable.Repeat(chars, passLength)
                      .Select(s => s[random.Next(s.Length)])
                      .ToArray());
        return result;
    }

Vui lòng giải thích câu trả lời của bạn
Linus

1
Chức năng này hoạt động rất tốt với một vài thay đổi. 1. Đã thêm entropy nếu bạn đang thực hiện nhiều cuộc gọi cùng một lúc. Điều này có nghĩa là được gọi là Ngủ () hoặc một số hàm gây entropy khác giữa các cuộc gọi. 2. Tăng số lượng và tính ngẫu nhiên của các ký tự nguồn. Tôi đã tạo một chuỗi 500 mật khẩu char với keypass không bao gồm một loạt các ký tự tương tự và có thể thoát khác mà tôi không muốn xử lý và sử dụng chuỗi ký tự 2000 kết quả. Sự ngẫu nhiên chỉ sau 100ms Entropy là khá tốt.
Wizengamot

2

Tôi sẽ thêm một câu trả lời không đúng đắn cho cái nồi.

Tôi có một trường hợp sử dụng khi tôi cần mật khẩu ngẫu nhiên để liên lạc với máy, vì vậy tôi không có bất kỳ yêu cầu nào về khả năng đọc của con người. Tôi cũng không có quyền truy cập Membership.GeneratePasswordvào dự án của mình và không muốn thêm phụ thuộc.

Tôi khá chắc chắn Membership.GeneratePasswordđang làm một cái gì đó tương tự như thế này, nhưng ở đây bạn có thể điều chỉnh các nhóm nhân vật để rút ra.

public static class PasswordGenerator
{
    private readonly static Random _rand = new Random();

    public static string Generate(int length = 24)
    {
        const string lower = "abcdefghijklmnopqrstuvwxyz";
        const string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        const string number = "1234567890";
        const string special = "!@#$%^&*_-=+";

        // Get cryptographically random sequence of bytes
        var bytes = new byte[length];
        new RNGCryptoServiceProvider().GetBytes(bytes);

        // Build up a string using random bytes and character classes
        var res = new StringBuilder();
        foreach(byte b in bytes)
        {
            // Randomly select a character class for each byte
            switch (_rand.Next(4))
            {
                // In each case use mod to project byte b to the correct range
                case 0:
                    res.Append(lower[b % lower.Count()]);
                    break;
                case 1:
                    res.Append(upper[b % upper.Count()]);
                    break;
                case 2:
                    res.Append(number[b % number.Count()]);
                    break;
                case 3:
                    res.Append(special[b % special.Count()]);
                    break;
            }
        }
        return res.ToString();
    }
}

Và một số ví dụ đầu ra:

PasswordGenerator.Generate(12)
"pzY=64@-ChS$"
"BG0OsyLbYnI_"
"l9#5^2&adj_i"
"#++Ws9d$%O%X"
"IWhdIN-#&O^s"

Để tránh các khiếu nại về việc sử dụng Random: Nguồn ngẫu nhiên chính vẫn là RNG tiền điện tử. Ngay cả khi bạn có thể xác định trước một cách chắc chắn trình tự phát ra Random(nói nó chỉ được sản xuất 1), bạn vẫn sẽ không biết char tiếp theo sẽ được chọn (mặc dù điều đó sẽ hạn chế phạm vi khả năng).

Một phần mở rộng đơn giản sẽ là thêm trọng số cho các bộ ký tự khác nhau, có thể đơn giản như tăng giá trị tối đa và thêm các trường hợp rơi để tăng trọng lượng.

switch (_rand.Next(6))
{
    // Prefer letters 2:1
    case 0:
    case 1:
        res.Append(lower[b % lower.Count()]);
        break;
    case 2:
    case 3:
        res.Append(upper[b % upper.Count()]);
        break;
    case 4:
        res.Append(number[b % number.Count()]);
        break;
    case 5:
        res.Append(special[b % special.Count()]);
        break;
}

Đối với một trình tạo mật khẩu ngẫu nhiên nhân văn hơn, tôi đã từng triển khai một hệ thống nhanh chóng bằng cách sử dụng danh sách từ xúc xắc EFF .


1

Tôi thích nhìn vào việc tạo mật khẩu, giống như tạo khóa phần mềm. Bạn nên chọn từ một loạt các nhân vật tuân theo một thực tiễn tốt. Lấy những gì @ Radu094 trả lời và sửa đổi nó để tuân theo thực tiễn tốt. Đừng đặt từng chữ cái trong mảng ký tự. Một số chữ cái khó nói hoặc hiểu qua điện thoại.

Bạn cũng nên xem xét sử dụng tổng kiểm tra mật khẩu đã được tạo để đảm bảo rằng nó được tạo bởi bạn. Một cách tốt để thực hiện điều này là sử dụng thuật toán LUHN .


1

Đây là những gì tôi đặt lại với nhau một cách nhanh chóng.

    public string GeneratePassword(int len)
    {
        string res = "";
        Random rnd = new Random();
        while (res.Length < len) res += (new Func<Random, string>((r) => {
            char c = (char)((r.Next(123) * DateTime.Now.Millisecond % 123)); 
            return (Char.IsLetterOrDigit(c)) ? c.ToString() : ""; 
        }))(rnd);
        return res;
    }

1

Tôi sử dụng mã này để tạo mật khẩu với thành phần cân bằng của bảng chữ cái, số và ký tự không_alpha_numeric.

public static string GeneratePassword(int Length, int NonAlphaNumericChars)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        string allowedNonAlphaNum = "!@#$%^&*()_-+=[{]};:<>|./?";
        string pass = "";
        Random rd = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < Length; i++)
        {
            if (rd.Next(1) > 0 && NonAlphaNumericChars > 0)
            {
                pass += allowedNonAlphaNum[rd.Next(allowedNonAlphaNum.Length)];
                NonAlphaNumericChars--;
            }
            else
            {
                pass += allowedChars[rd.Next(allowedChars.Length)];
            }
        }
        return pass;
    }

0

Điều này là ngắn và nó hoạt động tuyệt vời cho tôi.

public static string GenerateRandomCode(int length)
{
    Random rdm = new Random();
    StringBuilder sb = new StringBuilder();

    for(int i = 0; i < length; i++)
        sb.Append(Convert.ToChar(rdm.Next(101,132)));

    return sb.ToString();
}

Nó có thể "hoạt động", nhưng nó chắc chắn không an toàn. Mật khẩu cần được bảo mật.
CodeInChaos

Tôi nghĩ mật khẩu ngẫu nhiên là mật khẩu tạm thời. Đừng xem tại sao họ phải an toàn và ngay cả khi họ làm vậy, bạn có thể thêm số và ký tự đặc biệt trong phạm vi.
dùng1058637

1
Thêm số và ký tự đặc biệt sẽ không cải thiện bảo mật nếu bạn tạo chúng bằng PRNG dự đoán. Nếu bạn biết khi nào mật khẩu được tạo, bạn có thể thu hẹp chỉ còn một vài ứng viên.
CodeInChaos

0

Trên trang web của tôi, tôi sử dụng phương pháp này:

    //Symb array
    private const string _SymbolsAll = "~`!@#$%^&*()_+=-\\|[{]}'\";:/?.>,<";

    //Random symb
    public string GetSymbol(int Length)
    {
        Random Rand = new Random(DateTime.Now.Millisecond);
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < Length; i++)
            result.Append(_SymbolsAll[Rand.Next(0, _SymbolsAll.Length)]);
        return result.ToString();
    }

Chỉnh sửa chuỗi _SymbolsAllcho danh sách mảng của bạn.


Như đã nêu trong mô tả chỉnh sửa. Nếu bạn liên kết đến trang web của mình mà không phải là tài liệu tham khảo mã, bạn hoàn toàn quảng cáo sẽ khiến nó bị spam, vì vậy hãy xóa liên kết đó khỏi câu trả lời của bạn.
Bowdzone 30/03/2015

0

Đã thêm một số mã bổ sung cho câu trả lời được chấp nhận. Nó cải thiện câu trả lời chỉ bằng cách sử dụng Ngẫu nhiên và cho phép một số tùy chọn mật khẩu. Tôi cũng thích một số tùy chọn từ câu trả lời KeePass nhưng không muốn đưa tệp thực thi vào giải pháp của mình.

private string RandomPassword(int length, bool includeCharacters, bool includeNumbers, bool includeUppercase, bool includeNonAlphaNumericCharacters, bool includeLookAlikes)
{
    if (length < 8 || length > 128) throw new ArgumentOutOfRangeException("length");
    if (!includeCharacters && !includeNumbers && !includeNonAlphaNumericCharacters) throw new ArgumentException("RandomPassword-Key arguments all false, no values would be returned");

    string pw = "";
    do
    {
        pw += System.Web.Security.Membership.GeneratePassword(128, 25);
        pw = RemoveCharacters(pw, includeCharacters, includeNumbers, includeUppercase, includeNonAlphaNumericCharacters, includeLookAlikes);
    } while (pw.Length < length);

    return pw.Substring(0, length);
}

private string RemoveCharacters(string passwordString, bool includeCharacters, bool includeNumbers, bool includeUppercase, bool includeNonAlphaNumericCharacters, bool includeLookAlikes)
{
    if (!includeCharacters)
    {
        var remove = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
        foreach (string r in remove)
        {
            passwordString = passwordString.Replace(r, string.Empty);
            passwordString = passwordString.Replace(r.ToUpper(), string.Empty);
        }
    }

    if (!includeNumbers)
    {
        var remove = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
        foreach (string r in remove)
            passwordString = passwordString.Replace(r, string.Empty);
    }

    if (!includeUppercase)
        passwordString = passwordString.ToLower();

    if (!includeNonAlphaNumericCharacters)
    {
        var remove = new string[] { "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "=", "{", "}", "[", "]", "|", "\\", ":", ";", "<", ">", "/", "?", "." };
        foreach (string r in remove)
            passwordString = passwordString.Replace(r, string.Empty);
    }

    if (!includeLookAlikes)
    {
        var remove = new string[] { "(", ")", "0", "O", "o", "1", "i", "I", "l", "|", "!", ":", ";" };
        foreach (string r in remove)
            passwordString = passwordString.Replace(r, string.Empty);
    }

    return passwordString;
}

Đây là liên kết đầu tiên khi tôi tìm kiếm để tạo mật khẩu ngẫu nhiên và sau đây nằm ngoài phạm vi cho câu hỏi hiện tại nhưng có thể quan trọng để xem xét.

  • Dựa trên giả định System.Web.Security.Membership.GeneratePasswordđược bảo mật bằng mật mã với tối thiểu 20% các ký tự là Không chữ và số.
  • Không chắc chắn nếu loại bỏ các ký tự và chuỗi bổ sung được coi là thực hành tốt trong trường hợp này và cung cấp đủ entropy.
  • Có thể muốn xem xét triển khai theo một cách nào đó với SecureString để lưu trữ mật khẩu an toàn trong bộ nhớ.

FYI, bạn không cần phải bao gồm tệp thực thi KeyPass, vì nó là nguồn mở (mã nguồn có sẵn để tải xuống tại đây )
Alex Klaus

0

validChars có thể là bất kỳ cấu trúc nào, nhưng tôi đã quyết định chọn dựa trên phạm vi mã ascii loại bỏ các ký tự điều khiển. Trong ví dụ này, nó là một chuỗi 12 ký tự.

string validChars = String.Join("", Enumerable.Range(33, (126 - 33)).Where(i => !(new int[] { 34, 38, 39, 44, 60, 62, 96 }).Contains(i)).Select(i => { return (char)i; }));
string.Join("", Enumerable.Range(1, 12).Select(i => { return validChars[(new Random(Guid.NewGuid().GetHashCode())).Next(0, validChars.Length - 1)]; }))

0
 Generate random password of specified length with 
  - Special characters   
  - Number
  - Lowecase
  - Uppercase

  public static string CreatePassword(int length = 12)
    {
        const string lower = "abcdefghijklmnopqrstuvwxyz";
        const string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        const string number = "1234567890";
        const string special = "!@#$%^&*";

        var middle = length / 2;
        StringBuilder res = new StringBuilder();
        Random rnd = new Random();
        while (0 < length--)
        {
            if (middle == length)
            {
                res.Append(number[rnd.Next(number.Length)]);
            }
            else if (middle - 1 == length)
            {
                res.Append(special[rnd.Next(special.Length)]);
            }
            else
            {
                if (length % 2 == 0)
                {
                    res.Append(lower[rnd.Next(lower.Length)]);
                }
                else
                {
                    res.Append(upper[rnd.Next(upper.Length)]);
                }
            }
        }
        return res.ToString();
    }

Mã chỉ trả lời không được khuyến khích vì họ không cung cấp nhiều thông tin cho độc giả trong tương lai, vui lòng cung cấp một số giải thích cho những gì bạn đã viết
WhatsThePoint

Tạo cùng một mật khẩu nhiều lần. Cần phải có ví dụ Randomnhư tĩnh
trailmax

Xin lưu ý rằng câu trả lời này sẽ tạo cùng một mật khẩu nếu được gọi nhiều lần liên tiếp !!! Phải có thêm Entropy giữa các cuộc gọi nếu bạn muốn sử dụng chức năng gán mật khẩu bằng cách sử dụng mã cho nhiều bản ghi cùng một lúc. Vẫn hữu ích mặc dù ....
Wizengamot

0

Gói này cho phép bạn tạo một mật khẩu ngẫu nhiên trong khi lưu loát chỉ ra những ký tự cần chứa (nếu cần):

https://github.com/prjseal/PasswordGenerator/

Thí dụ:

var pwd = new Password().IncludeLowercase().IncludeUppercase().IncludeSpecial();
var password = pwd.Next();

0

Nếu bạn muốn sử dụng việc tạo số ngẫu nhiên an toàn bằng mật mã được System.Web.Security.Membership.GeneratePassword sử dụng nhưng cũng muốn giới hạn ký tự được đặt thành các ký tự chữ và số, bạn có thể lọc kết quả bằng biểu thức chính quy:

static string GeneratePassword(int characterCount)
{
    string password = String.Empty;
    while(password.Length < characterCount)
        password += Regex.Replace(System.Web.Security.Membership.GeneratePassword(128, 0), "[^a-zA-Z0-9]", string.Empty);
    return password.Substring(0, characterCount);
}

-3
public string Sifre_Uret(int boy, int noalfa)
{

    //  01.03.2016   
    // Genel amaçlı şifre üretme fonksiyonu


    //Fonskiyon 128 den büyük olmasına izin vermiyor.
    if (boy > 128 ) { boy = 128; }
    if (noalfa > 128) { noalfa = 128; }
    if (noalfa > boy) { noalfa = boy; }


    string passch = System.Web.Security.Membership.GeneratePassword(boy, noalfa);

    //URL encoding ve Url Pass + json sorunu yaratabilecekler pass ediliyor.
    //Microsoft Garanti etmiyor. Alfa Sayısallar Olabiliyorimiş . !@#$%^&*()_-+=[{]};:<>|./?.
    //https://msdn.microsoft.com/tr-tr/library/system.web.security.membership.generatepassword(v=vs.110).aspx


    //URL ve Json ajax lar için filtreleme
    passch = passch.Replace(":", "z");
    passch = passch.Replace(";", "W");
    passch = passch.Replace("'", "t");
    passch = passch.Replace("\"", "r");
    passch = passch.Replace("/", "+");
    passch = passch.Replace("\\", "e");

    passch = passch.Replace("?", "9");
    passch = passch.Replace("&", "8");
    passch = passch.Replace("#", "D");
    passch = passch.Replace("%", "u");
    passch = passch.Replace("=", "4");
    passch = passch.Replace("~", "1");

    passch = passch.Replace("[", "2");
    passch = passch.Replace("]", "3");
    passch = passch.Replace("{", "g");
    passch = passch.Replace("}", "J");


    //passch = passch.Replace("(", "6");
    //passch = passch.Replace(")", "0");
    //passch = passch.Replace("|", "p");
    //passch = passch.Replace("@", "4");
    //passch = passch.Replace("!", "u");
    //passch = passch.Replace("$", "Z");
    //passch = passch.Replace("*", "5");
    //passch = passch.Replace("_", "a");

    passch = passch.Replace(",", "V");
    passch = passch.Replace(".", "N");
    passch = passch.Replace("+", "w");
    passch = passch.Replace("-", "7");





    return passch;



}

Bạn có thể giải thích những gì mã của bạn làm, và tại sao? Từ đánh giá
Wai Ha Lee

Mã chỉ trả lời mà không có lời giải thích có khả năng bị xóa.
Rook

-4

Chèn một bộ định thời gian: timer1, 2 nút: button1, button2, 1 textBox: textBox1 và comboBox: comboBox1. Hãy chắc chắn rằng bạn tuyên bố:

int count = 0;

Mã nguồn:

 private void button1_Click(object sender, EventArgs e)
    {
    // This clears the textBox, resets the count, and starts the timer
        count = 0;
        textBox1.Clear();
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
    // This generates the password, and types it in the textBox
        count += 1;
            string possible = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
            string psw = "";
            Random rnd = new Random { };
            psw += possible[rnd.Next(possible.Length)];
            textBox1.Text += psw;
            if (count == (comboBox1.SelectedIndex + 1))
            {
                timer1.Stop();
            }
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        // This adds password lengths to the comboBox to choose from.
        comboBox1.Items.Add("1");
        comboBox1.Items.Add("2");
        comboBox1.Items.Add("3");
        comboBox1.Items.Add("4");
        comboBox1.Items.Add("5");
        comboBox1.Items.Add("6");
        comboBox1.Items.Add("7");
        comboBox1.Items.Add("8");
        comboBox1.Items.Add("9");
        comboBox1.Items.Add("10");
        comboBox1.Items.Add("11");
        comboBox1.Items.Add("12");
    }
    private void button2_click(object sender, EventArgs e)
    {
        // This encrypts the password
        tochar = textBox1.Text;
        textBox1.Clear();
        char[] carray = tochar.ToCharArray();
        for (int i = 0; i < carray.Length; i++)
        {
            int num = Convert.ToInt32(carray[i]) + 10;
            string cvrt = Convert.ToChar(num).ToString();
            textBox1.Text += cvrt;
        }
    }

1
Đừng sử dụng System.Randomđể bảo mật.
CodeInChaos
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.