吴晓阳
发布于 2025-09-23 / 2 阅读
0

随机密码生成器

// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!

using System.Security.Cryptography;

namespace Admin.NET.Core;

/// <summary>
/// 密码生成工具类
/// </summary>
public static class PasswordHelper
{
    /// <summary>
    /// 默认密码字符集
    /// </summary>
    private static readonly string LowercaseChars = "abcdefghijklmnopqrstuvwxyz";
    private static readonly string UppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static readonly string DigitChars = "0123456789";
    private static readonly string SpecialChars = "!@#$%^&*()_+-=[]{}|;:,.<>?";

    /// <summary>
    /// 密码生成选项
    /// </summary>
    public class PasswordOptions
    {
        /// <summary>
        /// 密码长度,默认12位
        /// </summary>
        public int Length { get; set; } = 12;

        /// <summary>
        /// 是否包含小写字母,默认true
        /// </summary>
        public bool IncludeLowercase { get; set; } = true;

        /// <summary>
        /// 是否包含大写字母,默认true
        /// </summary>
        public bool IncludeUppercase { get; set; } = true;

        /// <summary>
        /// 是否包含数字,默认true
        /// </summary>
        public bool IncludeDigits { get; set; } = true;

        /// <summary>
        /// 是否包含特殊字符,默认true
        /// </summary>
        public bool IncludeSpecialChars { get; set; } = true;

        /// <summary>
        /// 排除的字符,默认空
        /// </summary>
        public string ExcludeChars { get; set; } = string.Empty;

        /// <summary>
        /// 是否排除相似字符(如0、O、l、I等),默认false
        /// </summary>
        public bool ExcludeSimilarChars { get; set; } = false;

        /// <summary>
        /// 是否排除歧义字符,默认false
        /// </summary>
        public bool ExcludeAmbiguousChars { get; set; } = false;
    }

    /// <summary>
    /// 生成随机密码
    /// </summary>
    /// <param name="options">密码生成选项</param>
    /// <returns>生成的密码</returns>
    public static string GeneratePassword(PasswordOptions options = null)
    {
        options ??= new PasswordOptions();

        // 验证选项
        ValidateOptions(options);

        // 构建字符集
        var charSet = BuildCharSet(options);
        if (string.IsNullOrEmpty(charSet))
            throw new ArgumentException("至少需要包含一种字符类型");

        // 生成密码
        var password = new char[options.Length];
        var random = RandomNumberGenerator.Create();

        // 确保每种类型的字符至少出现一次
        var requiredChars = GetRequiredChars(options);
        for (int i = 0; i < requiredChars.Length; i++)
        {
            password[i] = requiredChars[i];
        }

        // 填充剩余位置
        for (int i = requiredChars.Length; i < options.Length; i++)
        {
            password[i] = GetRandomChar(charSet, random);
        }

        // 打乱密码字符顺序
        ShufflePassword(password, random);

        return new string(password);
    }

    /// <summary>
    /// 生成简单密码(仅数字)
    /// </summary>
    /// <param name="length">密码长度</param>
    /// <returns>生成的密码</returns>
    public static string GenerateSimplePassword(int length = 6)
    {
        var options = new PasswordOptions
        {
            Length = length,
            IncludeLowercase = false,
            IncludeUppercase = false,
            IncludeDigits = true,
            IncludeSpecialChars = false
        };
        return GeneratePassword(options);
    }

    /// <summary>
    /// 生成强密码
    /// </summary>
    /// <param name="length">密码长度,默认16位</param>
    /// <returns>生成的密码</returns>
    public static string GenerateStrongPassword(int length = 16)
    {
        var options = new PasswordOptions
        {
            Length = length,
            IncludeLowercase = true,
            IncludeUppercase = true,
            IncludeDigits = true,
            IncludeSpecialChars = true,
            ExcludeSimilarChars = true,
            ExcludeAmbiguousChars = true
        };
        return GeneratePassword(options);
    }

    /// <summary>
    /// 生成记忆密码(易读易记)
    /// </summary>
    /// <param name="length">密码长度,默认12位</param>
    /// <returns>生成的密码</returns>
    public static string GenerateMemorablePassword(int length = 12)
    {
        var options = new PasswordOptions
        {
            Length = length,
            IncludeLowercase = true,
            IncludeUppercase = true,
            IncludeDigits = true,
            IncludeSpecialChars = false,
            ExcludeSimilarChars = true,
            ExcludeAmbiguousChars = true
        };
        return GeneratePassword(options);
    }

    /// <summary>
    /// 验证密码强度
    /// </summary>
    /// <param name="password">要验证的密码</param>
    /// <returns>密码强度等级</returns>
    public static PasswordStrength ValidatePasswordStrength(string password)
    {
        if (string.IsNullOrEmpty(password))
            return PasswordStrength.VeryWeak;

        int score = 0;
        bool hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false;

        foreach (char c in password)
        {
            if (char.IsLower(c)) hasLower = true;
            else if (char.IsUpper(c)) hasUpper = true;
            else if (char.IsDigit(c)) hasDigit = true;
            else if (IsSpecialChar(c)) hasSpecial = true;
        }

        // 长度评分
        if (password.Length >= 8) score += 1;
        if (password.Length >= 12) score += 1;
        if (password.Length >= 16) score += 1;

        // 字符类型评分
        if (hasLower) score += 1;
        if (hasUpper) score += 1;
        if (hasDigit) score += 1;
        if (hasSpecial) score += 1;

        // 复杂度评分
        if (password.Length >= 8 && hasLower && hasUpper && hasDigit) score += 1;
        if (password.Length >= 12 && hasLower && hasUpper && hasDigit && hasSpecial) score += 1;

        return score switch
        {
            <= 2 => PasswordStrength.VeryWeak,
            <= 4 => PasswordStrength.Weak,
            <= 6 => PasswordStrength.Medium,
            <= 8 => PasswordStrength.Strong,
            _ => PasswordStrength.VeryStrong
        };
    }

    /// <summary>
    /// 检查密码是否满足要求
    /// </summary>
    /// <param name="password">要检查的密码</param>
    /// <param name="minLength">最小长度</param>
    /// <param name="requireLowercase">是否需要小写字母</param>
    /// <param name="requireUppercase">是否需要大写字母</param>
    /// <param name="requireDigits">是否需要数字</param>
    /// <param name="requireSpecialChars">是否需要特殊字符</param>
    /// <returns>是否满足要求</returns>
    public static bool CheckPasswordRequirements(string password, int minLength = 8, 
        bool requireLowercase = true, bool requireUppercase = true, 
        bool requireDigits = true, bool requireSpecialChars = false)
    {
        if (string.IsNullOrEmpty(password) || password.Length < minLength)
            return false;

        bool hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false;

        foreach (char c in password)
        {
            if (char.IsLower(c)) hasLower = true;
            else if (char.IsUpper(c)) hasUpper = true;
            else if (char.IsDigit(c)) hasDigit = true;
            else if (IsSpecialChar(c)) hasSpecial = true;
        }

        return (!requireLowercase || hasLower) &&
               (!requireUppercase || hasUpper) &&
               (!requireDigits || hasDigit) &&
               (!requireSpecialChars || hasSpecial);
    }

    /// <summary>
    /// 密码强度枚举
    /// </summary>
    public enum PasswordStrength
    {
        /// <summary>
        /// 非常弱
        /// </summary>
        VeryWeak,
        /// <summary>
        /// 弱
        /// </summary>
        Weak,
        /// <summary>
        /// 中等
        /// </summary>
        Medium,
        /// <summary>
        /// 强
        /// </summary>
        Strong,
        /// <summary>
        /// 非常强
        /// </summary>
        VeryStrong
    }

    #region 私有方法

    /// <summary>
    /// 验证密码生成选项
    /// </summary>
    private static void ValidateOptions(PasswordOptions options)
    {
        if (options.Length < 1)
            throw new ArgumentException("密码长度必须大于0", nameof(options.Length));

        if (options.Length > 128)
            throw new ArgumentException("密码长度不能超过128位", nameof(options.Length));

        if (!options.IncludeLowercase && !options.IncludeUppercase && 
            !options.IncludeDigits && !options.IncludeSpecialChars)
            throw new ArgumentException("至少需要包含一种字符类型");
    }

    /// <summary>
    /// 构建字符集
    /// </summary>
    private static string BuildCharSet(PasswordOptions options)
    {
        var charSet = string.Empty;

        if (options.IncludeLowercase)
            charSet += GetFilteredChars(LowercaseChars, options);

        if (options.IncludeUppercase)
            charSet += GetFilteredChars(UppercaseChars, options);

        if (options.IncludeDigits)
            charSet += GetFilteredChars(DigitChars, options);

        if (options.IncludeSpecialChars)
            charSet += GetFilteredChars(SpecialChars, options);

        return charSet;
    }

    /// <summary>
    /// 获取过滤后的字符
    /// </summary>
    private static string GetFilteredChars(string chars, PasswordOptions options)
    {
        var filteredChars = chars;

        // 排除指定字符
        if (!string.IsNullOrEmpty(options.ExcludeChars))
        {
            foreach (char c in options.ExcludeChars)
            {
                filteredChars = filteredChars.Replace(c.ToString(), "");
            }
        }

        // 排除相似字符
        if (options.ExcludeSimilarChars)
        {
            filteredChars = filteredChars.Replace("0", "").Replace("O", "").Replace("o", "")
                                        .Replace("1", "").Replace("l", "").Replace("I", "");
        }

        // 排除歧义字符
        if (options.ExcludeAmbiguousChars)
        {
            filteredChars = filteredChars.Replace("B", "").Replace("8", "")
                                        .Replace("G", "").Replace("6", "")
                                        .Replace("S", "").Replace("5", "");
        }

        return filteredChars;
    }

    /// <summary>
    /// 获取必需的字符
    /// </summary>
    private static char[] GetRequiredChars(PasswordOptions options)
    {
        var requiredChars = new List<char>();
        var random = RandomNumberGenerator.Create();

        if (options.IncludeLowercase)
        {
            var chars = GetFilteredChars(LowercaseChars, options);
            if (!string.IsNullOrEmpty(chars))
                requiredChars.Add(GetRandomChar(chars, random));
        }

        if (options.IncludeUppercase)
        {
            var chars = GetFilteredChars(UppercaseChars, options);
            if (!string.IsNullOrEmpty(chars))
                requiredChars.Add(GetRandomChar(chars, random));
        }

        if (options.IncludeDigits)
        {
            var chars = GetFilteredChars(DigitChars, options);
            if (!string.IsNullOrEmpty(chars))
                requiredChars.Add(GetRandomChar(chars, random));
        }

        if (options.IncludeSpecialChars)
        {
            var chars = GetFilteredChars(SpecialChars, options);
            if (!string.IsNullOrEmpty(chars))
                requiredChars.Add(GetRandomChar(chars, random));
        }

        return requiredChars.ToArray();
    }

    /// <summary>
    /// 获取随机字符
    /// </summary>
    private static char GetRandomChar(string charSet, RandomNumberGenerator random)
    {
        var randomBytes = new byte[4];
        random.GetBytes(randomBytes);
        var randomValue = Math.Abs(BitConverter.ToInt32(randomBytes, 0));
        return charSet[randomValue % charSet.Length];
    }

    /// <summary>
    /// 打乱密码字符顺序
    /// </summary>
    private static void ShufflePassword(char[] password, RandomNumberGenerator random)
    {
        for (int i = password.Length - 1; i > 0; i--)
        {
            var randomBytes = new byte[4];
            random.GetBytes(randomBytes);
            var randomValue = Math.Abs(BitConverter.ToInt32(randomBytes, 0));
            int j = randomValue % (i + 1);
            (password[i], password[j]) = (password[j], password[i]);
        }
    }

    /// <summary>
    /// 判断是否为特殊字符
    /// </summary>
    private static bool IsSpecialChar(char c)
    {
        return SpecialChars.Contains(c);
    }

    #endregion
}

使用方法:

// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!

namespace Admin.NET.Core;

/// <summary>
/// 密码生成工具类使用示例
/// </summary>
public static class PasswordHelperExample
{
    /// <summary>
    /// 使用示例
    /// </summary>
    public static void UsageExamples()
    {
        // 1. 生成默认密码(12位,包含大小写字母、数字、特殊字符)
        var defaultPassword = PasswordHelper.GeneratePassword(new PasswordHelper.PasswordOptions { Length = 8 });
        Console.WriteLine($"默认密码: {defaultPassword}");

        // 2. 生成简单密码(仅数字)
        var simplePassword = PasswordHelper.GenerateSimplePassword(8);
        Console.WriteLine($"简单密码: {simplePassword}");

        // 3. 生成强密码
        var strongPassword = PasswordHelper.GenerateStrongPassword(20);
        Console.WriteLine($"强密码: {strongPassword}");

        // 4. 生成记忆密码(易读易记)
        var memorablePassword = PasswordHelper.GenerateMemorablePassword(14);
        Console.WriteLine($"记忆密码: {memorablePassword}");

        // 5. 自定义密码生成选项
        var customOptions = new PasswordHelper.PasswordOptions
        {
            Length = 16,
            IncludeLowercase = true,
            IncludeUppercase = true,
            IncludeDigits = true,
            IncludeSpecialChars = true,
            ExcludeSimilarChars = true,  // 排除相似字符
            ExcludeAmbiguousChars = true, // 排除歧义字符
            ExcludeChars = "0O1lI"        // 排除指定字符
        };
        var customPassword = PasswordHelper.GeneratePassword(customOptions);
        Console.WriteLine($"自定义密码: {customPassword}");

        // 6. 验证密码强度
        var testPasswords = new[]
        {
            "123456",
            "password",
            "Password123",
            "MyStr0ng!P@ssw0rd",
            "VeryC0mpl3x&P@ssw0rd!2024"
        };

        foreach (var pwd in testPasswords)
        {
            var strength = PasswordHelper.ValidatePasswordStrength(pwd);
            Console.WriteLine($"密码: {pwd} - 强度: {strength}");
        }

        // 7. 检查密码是否满足要求
        var testPassword = "MyPassword123!";
        var meetsRequirements = PasswordHelper.CheckPasswordRequirements(
            testPassword, 
            minLength: 8, 
            requireLowercase: true, 
            requireUppercase: true, 
            requireDigits: true, 
            requireSpecialChars: true
        );
        Console.WriteLine($"密码 '{testPassword}' 是否满足要求: {meetsRequirements}");

        // 8. 批量生成密码
        Console.WriteLine("\n批量生成密码:");
        for (int i = 1; i <= 5; i++)
        {
            var batchPassword = PasswordHelper.GeneratePassword();
            var strength = PasswordHelper.ValidatePasswordStrength(batchPassword);
            Console.WriteLine($"密码 {i}: {batchPassword} (强度: {strength})");
        }
    }

    /// <summary>
    /// 密码策略验证示例
    /// </summary>
    public static void PasswordPolicyExample()
    {
        // 企业级密码策略
        var enterprisePolicy = new PasswordHelper.PasswordOptions
        {
            Length = 12,
            IncludeLowercase = true,
            IncludeUppercase = true,
            IncludeDigits = true,
            IncludeSpecialChars = true,
            ExcludeSimilarChars = true,
            ExcludeAmbiguousChars = true
        };

        // 生成符合企业策略的密码
        var enterprisePassword = PasswordHelper.GeneratePassword(enterprisePolicy);
        Console.WriteLine($"企业级密码: {enterprisePassword}");

        // 验证密码强度
        var strength = PasswordHelper.ValidatePasswordStrength(enterprisePassword);
        Console.WriteLine($"密码强度: {strength}");

        // 检查是否满足企业要求
        var meetsEnterpriseRequirements = PasswordHelper.CheckPasswordRequirements(
            enterprisePassword,
            minLength: 12,
            requireLowercase: true,
            requireUppercase: true,
            requireDigits: true,
            requireSpecialChars: true
        );
        Console.WriteLine($"是否满足企业要求: {meetsEnterpriseRequirements}");
    }

    /// <summary>
    /// 不同场景的密码生成示例
    /// </summary>
    public static void DifferentScenariosExample()
    {
        Console.WriteLine("=== 不同场景的密码生成 ===");

        // 1. 用户注册密码
        var userPassword = PasswordHelper.GenerateMemorablePassword(10);
        Console.WriteLine($"用户注册密码: {userPassword}");

        // 2. 管理员密码
        var adminPassword = PasswordHelper.GenerateStrongPassword(16);
        Console.WriteLine($"管理员密码: {adminPassword}");

        // 3. API密钥
        var apiKey = PasswordHelper.GeneratePassword(new PasswordHelper.PasswordOptions
        {
            Length = 32,
            IncludeLowercase = true,
            IncludeUppercase = true,
            IncludeDigits = true,
            IncludeSpecialChars = false,
            ExcludeSimilarChars = true
        });
        Console.WriteLine($"API密钥: {apiKey}");

        // 4. 临时密码
        var tempPassword = PasswordHelper.GenerateSimplePassword(8);
        Console.WriteLine($"临时密码: {tempPassword}");

        // 5. 数据库密码
        var dbPassword = PasswordHelper.GeneratePassword(new PasswordHelper.PasswordOptions
        {
            Length = 20,
            IncludeLowercase = true,
            IncludeUppercase = true,
            IncludeDigits = true,
            IncludeSpecialChars = true,
            ExcludeChars = "!@#$%^&*()" // 排除可能引起问题的特殊字符
        });
        Console.WriteLine($"数据库密码: {dbPassword}");
    }
}