我的计算机安全课程需要帮助;在程序中我需要生成一个字符串的所有可能组合给定一组默认字符(字母,数字和一些特殊字符)。考虑到可能的长度为1到10个字符,我无法弄清楚如何正确地循环它们的方法。我能够创建一个简单的嵌套循环,适用于2位数,但我认为必须有一个更好的方法将其缩放到10个字符,并不需要复制粘贴循环再次lol。下面的第一个代码块是我对10位数的尝试,下面的代码是我2位数的尝试。任何帮助,即使在理解如何解决问题时也会非常感谢,谢谢。
String SALTCHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_$#-~";
for(int i =1;i<11;i++) {
String initialPW = StringUtils.repeat("a", i);
StringBuilder potentialPW = new StringBuilder(initialPW);
System.out.println("initial ps is "+initialPW);
for (int j=0;j<67;j++) {
String letterSwap = Character.toString(SALTCHARS.charAt(j));
System.out.println("The swap letter is "+letterSwap);
potentialPW.setCharAt(i-1, SALTCHARS.charAt(j));
String saltStr = potentialPW.toString();
System.out.println("The final pw guess is "+ saltStr);
for (int k = 0;k<i;k++) {
potentialPW.setCharAt(k, SALTCHARS.charAt(j));
saltStr = potentialPW.toString();
System.out.println("The final pw guess is "+ saltStr);
}
}
}
这是我对这个概念的尝试,但有2个字符
String[] possiblePasswords = new String[676];
int position = 0;
for (int i = 97;i<123;i++) {
for (int j = 97;j<123;j++) {
String firstLetter = Character.toString((char) i);
String secondLetter = Character.toString((char) j);
//System.out.println("Test for: "+ firstLetter+secondLetter);
possiblePasswords[position] = firstLetter + secondLetter;
position++;
}
}
答案 0 :(得分:2)
您需要使用回溯来生成给定长度的所有字符组合。如果生成的字符串的长度未修复,则需要使用递归,否则您将需要编写那么多嵌套循环。我编写了一个简单的C ++程序,它也是如此。但是,长度[1,10]会有很多可能的组合,并且创建所有这些组合会导致我的系统堆栈溢出(因为我正在使用递归)。但是你可以浏览代码并理解这样做的基本思路。如果你想执行这个代码来检查它,我建议你将hi的值更改为低(2-3可能)或将域大小缩小到较小的字符数,否则会导致堆栈溢出。 (hi表示所生成的字符串的期望上限)。
#include<bits/stdc++.h>
using namespace std;
void create(int i,string domain,vector<bool>& included,string str,int len)
{
if(i==(len))
{
cout<<str<<endl;
return;
}
for(int j=0;j<domain.length();j++)
{
if(included[j]==1)
continue;
else
{
included[j]=1;
str+=domain[j];
create(i+1,domain,included,str,len);
included[j]=0;
str.pop_back();
}
}
}
int main()
{
string domain = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_$#-~";
int lo=1;
int hi=10;
for(int i=lo;i<=hi;i++)
{
int len=i;
string str;
vector<bool> included(domain.length(),0);
create(0,domain,included,str,len);
}
return 0;
}
答案 1 :(得分:1)
嗯......有意思?
我想我可能有一个可怕的想法。
为简单起见,我将使用两个有效字符A
和B
。
然后,假设我们想要为长度为2的字符串生成这两个字符的所有可能序列:
我们可以使用二维数组表示所有可能的2个长度字符串... 然后,说我们想要找到所有可能的3个长度字符串......
然后,我们可以通过迭代3D数组的每个元素,获得A
和B
的所有可能组合,以获得长度为3的字符串。我们知道有8种可能的结果(2 ^ 3),实际上有8个“立方体”,即AAA, AAB, ABA, ABB, BAA, BAB, BBA, BBB
。
等等...... 对于长度为4的字符串,创建一个4维数组... 看,告诉你这是一个可怕的想法。
现在你只需要弄清楚如何填充数组,然后就可以使用像Array.deepToString这样的东西来打印它了...... 这太可怕了,但我喜欢不得不进入其他方面来回答这个问题。
<小时/>
对此问题进行建模的另一种可能方法是将其视为一组 链轮(如flip clock):
(忽略第三轮有2个B的一帧,这是一个错误:P)
箭头指向“轮子”设置的组合。
当第一个'wheel'完成它的旋转时,它会将下一个'wheel'递增1.这将允许你循环遍历所有可能的组合。
这种行为可以通过创建一个带有'value'属性和'rotation'方法的wheel类来实现。每次调用旋转时,它都会循环显示它的值。 创建一组这些轮类,并使其在第一个轮完成一个完整的旋转/循环时,它将增加第二个轮。然后,一旦第二个轮子完成一个旋转,第三个轮子将被调用,依此类推......
连接并打印程序每一步的轮子值,这应该有效。