【问题标题】:Modify a String by modifying its byte array representation通过修改其字节数组表示来修改字符串
【发布时间】:2017-12-22 14:27:01
【问题描述】:

我想做什么

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

  • 为什么字节数组没有改变?
  • 我应该怎么做才能改变字节数组,使它代表下一个字符串

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

【问题讨论】:

    标签: java arrays string encoding byte


    【解决方案1】:

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

    for 循环似乎在逻辑上完全被打破了。如果你想把a 变成b,你可以打电话给toDecode[i]++。您的版本似乎试图将这些值当作位来操作,因此您会得到那些无法显示的 01 字符。

    您可能希望根据自己的需要保留一组有效字符(至少我想[a-zA-Z0-9],以及您想要的任何特殊字符)。然后,您可以使用validChars[] 的索引数组,其中0 代表第一个字符。

    然后您只需将每个数组索引从0 循环到validChars.length 并处理进位。在每次递增迭代后,您可以将索引映射到来自 validChars 的字节,以获取生成的 byte[],其中包含可用于密码的有效、可显示字符。

    此外,这实际上不是Rainbow Table,因为您似乎只是想预先计算所有哈希值,而彩虹表则在空间/时间上进行权衡。凭借最近的技术优势,无需以时间换空间,因为您可以花一点零钱购买数个 TB 的 SSD 磁盘,因此 Rainbow Tables 几乎绝迹了。

    【讨论】:

      猜你喜欢
      • 2018-04-25
      • 2020-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-13
      • 1970-01-01
      • 2016-05-04
      • 1970-01-01
      相关资源
      最近更新 更多