我想为所有4个字符的字符串(或任何数字但不相关的)的MD5哈希创建彩虹表。我想生成那4个字符串的字节数组表示
为了提高性能,我不想只创建String
并在其上调用getBytes
。 我想修改字节序列,使其成为下一个字符串的表示。
示例:
byte[] firstString = "aaaa".getBytes(ENCODING);
// I hash and store firstString
byte[] nextString = ???
System.out.println(new String(nextString));
// I want it to print "aaab". This should go up to "aaaz" and then go to "aaba". I'll add the number after.
我试图通过操纵二进制文件来增加它(来自SO上的答案):
byte[] toDecode = "aaaa".getBytes(ENCODING);
int cpt = 0;
String s;
boolean carry;
while (cpt < 15) {
cpt ++;
System.out.println(toDecode); // prints the byte array
s = DigestUtils.md5Hex(toDecode);
System.out.println(new String(toDecode + " : " + s);
carry = true;
// Yeah, I know this for can be simplified with a break, I'll do it later :(
for (int i = (toDecode.length - 1); i >= 0; i--) {
if (carry) {
if (toDecode[i] == 0) {
toDecode[i] = 1;
carry = false;
} else {
toDecode[i] = 0;
carry = true;
}
}
}
}
[B@4e25154f //The byte value, that's ok
aaaaaaaa : 3dbe00a167653a1aaee01d93e77e730e // The string and its hash
[B@4e25154f // Here, the byte array doesn't seem to be different!
: 7dea362b3fac8e00956a4952a3d4f474
[B@4e25154f
X : 7dea362b3fac8e00956a4952a3d4f474
[B@4e25154f
X : 7dea362b3fac8e00956a4952a3d4f474
[B@4e25154f
XX : 7dea362b3fac8e00956a4952a3d4f474
[B@4e25154f
X : 7dea362b3fac8e00956a4952a3d4f474
X
表示一个小方块,其中包含0和1,我无法粘贴它,它们不会打印在问题中。它们像二进制一样移动:第一个元素,第二个元素,然后是第二个和第一个,然后是第三个,等等......
我的猜测是我以某种方式修改了比特,这导致了这种变化
我不明白的是:
另一方面,如果您对我正在使用的方法有任何意见,请随意。
答案 0 :(得分:0)
[B@4e25154f
只是toString()
的默认byte[]
实现。由于您使用相同的byte[]
,因此无法进行更改。 byte[]
的内部内容确实发生了变化。
for
循环似乎在逻辑上完全被破坏了。如果您想将a
变为b
,则只需拨打toDecode[i]++
即可。您的版本似乎试图操纵值,就像它们是位一样,因此您可以获得无法显示的0
和1
个字符。
您可能希望保留一组有效字符,具体取决于您想要的内容(至少我想象[a-zA-Z0-9]
,以及您想要的任何特殊字符)。然后,您可以使用一系列索引到validChars[]
,0
代表第一个字符。
然后你只需要将每个数组索引从0
循环到validChars.length
并处理进位。在每次增量迭代之后,您可以将索引映射到validChars
中的字节,以获得包含可用于密码的有效,可显示字符的结果byte[]
。
这实际上并不是Rainbow Table,因为你似乎想要预先计算所有哈希值,而彩虹表做空间/时间权衡。凭借最近的技术优势,无需为空间换取时间,因为您可以购买几兆兆字节的SSD磁盘以进行小的更改,因此Rainbow Tables几乎绝迹。