Kotlin如何遍历所有排列组合以破解随机生成的密码
实现方案
规则确认
首先明确你给出的密码生成逻辑对应的固定规则:
- 数字段:取值范围为
0~999的整数,转为字符串后长度自然为1~3位,无需额外排列数字列表 - 小写字母段:3位可重复的小写字母(a~z)
- 大写字母段:3位可重复的大写字母(A~Z)
总组合量约为3090亿,仅适合学习原理使用,实际运行建议提前加终止逻辑。
最简嵌套循环实现
直接用多层嵌套循环遍历所有可能,匹配到目标密码后立即终止:
fun main() { // 原密码生成逻辑,得到目标密码 val lowerCase = listOf("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") val upperCase = listOf("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") val targetPassword = run { val numPart = (Math.random() * 999).toInt().toString() val l1 = lowerCase[(Math.random() * lowerCase.size).toInt()] val l2 = lowerCase[(Math.random() * lowerCase.size).toInt()] val l3 = lowerCase[(Math.random() * lowerCase.size).toInt()] val u1 = upperCase[(Math.random() * upperCase.size).toInt()] val u2 = upperCase[(Math.random() * upperCase.size).toInt()] val u3 = upperCase[(Math.random() * upperCase.size).toInt()] "$numPart$l1$l2$l3$u1$u2$u3" } println("目标密码为:$targetPassword") // 暴力遍历破解逻辑 var foundPassword: String? = null // 外层加标签,匹配到直接跳出所有循环 brute@ for (num in 0..999) { val numPart = num.toString() for (l1 in lowerCase) { for (l2 in lowerCase) { for (l3 in lowerCase) { val lowerPart = "$l1$l2$l3" for (u1 in upperCase) { for (u2 in upperCase) { for (u3 in upperCase) { val candidate = "$numPart$lowerPart$u1$u2$u3" if (candidate == targetPassword) { foundPassword = candidate break@brute } } } } } } } } println("破解得到密码:$foundPassword") }
优化方案(内存友好)
如果担心嵌套循环层级太多可读性差,可以用Kotlin的惰性序列生成笛卡尔积,避免一次性加载所有组合到内存:
// 生成所有小写3位组合的序列 val lowerSeq = lowerCase.asSequence() .flatMap { l1 -> lowerCase.asSequence().flatMap { l2 -> lowerCase.asSequence().map { l3 -> "$l1$l2$l3" } } } // 生成所有大写3位组合的序列 val upperSeq = upperCase.asSequence() .flatMap { u1 -> upperCase.asSequence().flatMap { u2 -> upperCase.asSequence().map { u3 -> "$u1$u2$u3" } } } // 遍历所有组合 var found: String? = null outer@ for (num in 0..999) { val numStr = num.toString() for (lower in lowerSeq) { for (upper in upperSeq) { val candidate = "$numStr$lower$upper" if (candidate == targetPassword) { found = candidate break@outer } } } }
注意事项
- 原生成逻辑中数字段的取值范围实际为
0~998(因Math.random()返回值不包含1),如需完全对齐可将数字循环范围改为0 until 999 - 原代码中
upperCase定义的是Char类型列表,拼接时会自动转String,建议统一改为String类型避免类型异常 - 由于总组合量过大,实际运行时建议缩小测试范围(比如限制数字为0~10,字母仅取前5个)验证逻辑正确性
内容的提问来源于stack exchange,提问作者Not found
相关产品推荐
相关产品推荐

