将长数组反转为字符串算法
Reverse long array to string algorithm
我需要反转以下将长数组转换为字符串的算法:
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 作为结果。
如果有人能说出这是什么算法或者我如何反转它就太好了。
感谢您的帮助
这不是所述的可解决问题,因为
- 您只使用
l[0]
,因此任何额外的 long
值都可以是任何值。
- 保证这个问题有
N << 16
个解法。虽然随机种子实际上是 64 位,但内部使用的值是 48 位。这意味着是否有任何解决方案,如果 long
种子至少有 16K 个解决方案。
你能做的是;
找到可以使用蛮力生成字符串的最小种子。对于短字符串,这不会花很长时间,但是如果您有 5-6 个字符,这将需要一段时间,而对于 7 个以上的字符,可能没有解决方案。
而不是生成所有 8 位值都相等的 8 位字符。您可以将范围限制为 space、A-Z、a-z 和 0-9。这意味着您可以拥有约 6 位的随机性、较短的种子和稍长的字符串。
顺便说一句,您可能会发现这个 post 很有趣,因为我使用人为的随机种子来生成特定序列。 http://vanillajava.blogspot.co.uk/2011/10/randomly-no-so-random.html
如果您想要一个确保您始终可以从 String 或 byte[] 重新创建原始 long 的过程,我建议使用加密。您可以将 UTF-8 编码的 String 或 byte[] 加密为另一个 byte[],后者可以进行 base64 编码以作为文本可读。 (或者您可以跳过加密并单独使用 base64)
我需要反转以下将长数组转换为字符串的算法:
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 作为结果。
如果有人能说出这是什么算法或者我如何反转它就太好了。
感谢您的帮助
这不是所述的可解决问题,因为
- 您只使用
l[0]
,因此任何额外的long
值都可以是任何值。 - 保证这个问题有
N << 16
个解法。虽然随机种子实际上是 64 位,但内部使用的值是 48 位。这意味着是否有任何解决方案,如果long
种子至少有 16K 个解决方案。
你能做的是;
找到可以使用蛮力生成字符串的最小种子。对于短字符串,这不会花很长时间,但是如果您有 5-6 个字符,这将需要一段时间,而对于 7 个以上的字符,可能没有解决方案。
而不是生成所有 8 位值都相等的 8 位字符。您可以将范围限制为 space、A-Z、a-z 和 0-9。这意味着您可以拥有约 6 位的随机性、较短的种子和稍长的字符串。
顺便说一句,您可能会发现这个 post 很有趣,因为我使用人为的随机种子来生成特定序列。 http://vanillajava.blogspot.co.uk/2011/10/randomly-no-so-random.html
如果您想要一个确保您始终可以从 String 或 byte[] 重新创建原始 long 的过程,我建议使用加密。您可以将 UTF-8 编码的 String 或 byte[] 加密为另一个 byte[],后者可以进行 base64 编码以作为文本可读。 (或者您可以跳过加密并单独使用 base64)