通过修改字节数组表示

时间:2017-12-22 14:27:02

标签: java arrays string encoding byte

我想做什么

我想为所有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,我无法粘贴它,它们不会打印在问题中。它们像二进制一样移动:第一个元素,第二个元素,然后是第二个和第一个,然后是第三个,等等...... 我的猜测是我以某种方式修改了比特,这导致了这种变化 我不明白的是:

  • 为什么字节数组不变?
  • 我应该怎么做才能更改字节数组,以便它代表下一个字符串

另一方面,如果您对我正在使用的方法有任何意见,请随意。

1 个答案:

答案 0 :(得分:0)

[B@4e25154f只是toString()的默认byte[]实现。由于您使用相同的byte[],因此无法进行更改。 byte[]的内部内容确实发生了变化。

for循环似乎在逻辑上完全被破坏了。如果您想将a变为b,则只需拨打toDecode[i]++即可。您的版本似乎试图操纵值,就像它们是位一样,因此您可以获得无法显示的01个字符。

您可能希望保留一组有效字符,具体取决于您想要的内容(至少我想象[a-zA-Z0-9],以及您想要的任何特殊字符)。然后,您可以使用一系列索引到validChars[]0代表第一个字符。

然后你只需要将每个数组索引从0循环到validChars.length并处理进位。在每次增量迭代之后,您可以将索引映射到validChars中的字节,以获得包含可用于密码的有效,可显示字符的结果byte[]

这实际上并不是Rainbow Table,因为你似乎想要预先计算所有哈希值,而彩虹表做空间/时间权衡。凭借最近的技术优势,无需为空间换取时间,因为您可以购买几兆兆字节的SSD磁盘以进行小的更改,因此Rainbow Tables几乎绝迹。