Unity & C#中如何生成无重复字符的随机密码
生成无重复字符的随机密码解决方案
你的当前代码会随机重复选取字符,要生成无重复字符的密码,核心是确保每次选取的字符未被使用过,同时必须注意密码长度不能超过字符池的总长度(你的PASSWORD_CHARS包含36个字符,所以length最大不能超过36)。以下是两种可行的实现方案:
方案一:基于可移除字符列表的随机选取
维护一个可用字符的列表,每次随机选取后从列表中移除该字符,彻底避免重复选取:
public static class StringUtils { private const string PASSWORD_CHARS = "0123456789abcdefghijklmnopqrstuvwxyz"; public static string GeneratePassword(int length) { // 校验长度合法性,防止无法生成无重复密码 if (length <= 0 || length > PASSWORD_CHARS.Length) throw new ArgumentOutOfRangeException(nameof(length), $"长度必须在1到{PASSWORD_CHARS.Length}之间"); var availableChars = new List<char>(PASSWORD_CHARS); var sb = new System.Text.StringBuilder(length); var r = new System.Random(); for (int i = 0; i < length; i++) { int pos = r.Next(availableChars.Count); char c = availableChars[pos]; sb.Append(c); availableChars.RemoveAt(pos); // 移除已选字符,避免重复 } return sb.ToString(); } }
方案二:基于字符数组洗牌的方式
使用经典的Fisher-Yates洗牌算法打乱字符池数组,直接截取前length个字符,实现简洁且高效:
public static class StringUtils { private const string PASSWORD_CHARS = "0123456789abcdefghijklmnopqrstuvwxyz"; public static string GeneratePassword(int length) { if (length <= 0 || length > PASSWORD_CHARS.Length) throw new ArgumentOutOfRangeException(nameof(length), $"长度必须在1到{PASSWORD_CHARS.Length}之间"); char[] charArray = PASSWORD_CHARS.ToCharArray(); var r = new System.Random(); // Fisher-Yates 洗牌算法打乱数组顺序 for (int i = charArray.Length - 1; i > 0; i--) { int j = r.Next(i + 1); // 交换数组元素 (charArray[i], charArray[j]) = (charArray[j], charArray[i]); } // 截取前length个无重复字符 return new string(charArray, 0, length); } }
方案特点说明
- 方案一逻辑直观,适合需要动态调整字符池的场景,每次移除已选字符的操作清晰可控。
- 方案二的洗牌算法时间复杂度为O(n),效率更高,代码更简洁,适合固定字符池的场景。
内容的提问来源于stack exchange,提问作者wndud 1731
相关产品推荐
相关产品推荐

