通过修改字节数组表示来修改字符串

问题描述 投票:0回答:1

What I want to do

我想为所有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.

What I did

我试图通过操纵二进制来增加它(来自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的小方块,我不能粘贴它,它们不会被打印在问题中。它们像二进制一样移动:第一个元素,第二个元素,然后是第二个和第一个,然后是第三个,等等...... 我的猜测是我以某种方式修改了比特,这导致了这种变化。 我不明白的是:

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

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

java arrays string encoding byte
1个回答
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几乎绝迹。

© www.soinside.com 2019 - 2024. All rights reserved.