我需要反转以下算法,将长数组转换为字符串:
public final class LongConverter {
private final long[] l;
public LongConverter(long[] paramArrayOfLong) {
this.l = paramArrayOfLong;
}
private void convertLong(long paramLong, byte[] paramArrayOfByte, int paramInt) {
int i = Math.min(paramArrayOfByte.length, paramInt + 8);
while (paramInt < i) {
paramArrayOfByte[paramInt] = ((byte) (int) paramLong);
paramLong >>= 8;
paramInt++;
}
}
public final String toString() {
int i = this.l.length;
byte[] arrayOfByte = new byte[8 * (i - 1)];
long l1 = this.l[0];
Random localRandom = new Random(l1);
for (int j = 1; j < i; j++) {
long l2 = localRandom.nextLong();
convertLong(this.l[j] ^ l2, arrayOfByte, 8 * (j - 1));
}
String str;
try {
str = new String(arrayOfByte, "UTF8");
} catch (UnsupportedEncodingException localUnsupportedEncodingException) {
throw new AssertionError(localUnsupportedEncodingException);
}
int k = str.indexOf(0);
if (-1 == k) {
return str;
}
return str.substring(0, k);
}
所以当我进行以下调用时
System.out.println(new LongConverter(new long[]{-6567892116040843544L, 3433539276790523832L}).toString());
结果打印 400 。
如果有人能说出这是什么算法或者我如何扭转它,那将会很棒。
感谢您的帮助
答案 0 :(得分:3)
这不是一个可解决的问题,因为
l[0]
,因此任何其他long
值都可以是任何内容。N << 16
个解决方案。虽然随机种子实际上是64位,但内部使用的值是48位。这意味着有任何解决方案,如果long
种子至少有16K解决方案。你能做的是;
找到使用强力生成弦的最小种子。对于一个短的字符串,这不会花费很长时间,但如果你有5-6个字符,这将需要一段时间,而对于7 +字符可能没有解决方案。
而不是生成所有8位值相等的8位字符。您可以将范围限制为空格,A-Z,a-z和0-9。这意味着您可以拥有~6位的随机性,更短的种子和稍长的字符串。
BTW您可能会发现这篇文章很有趣,我使用人为的随机种子生成特定的序列。 http://vanillajava.blogspot.co.uk/2011/10/randomly-no-so-random.html
如果您想要一个确保始终可以从String或byte []重新创建原始long的进程,我建议使用加密。您可以将已经UTF-8编码的字符串或字节[]加密到另一个字节[]中,该字节可以是base64编码的,可以作为文本读取。 (或者你可以跳过加密并单独使用base64)