我尝试将一些C代码转换为Java,但它的工作略有不同。它是XOR加密,对于某些数据,它返回相同的结果,所以我知道它非常接近,但对于某些数据,它不能完全相同(不同的结果)。
C代码(在x86 Windows上运行,使用Borland Builder编译):
void Crypt(unsigned char *data,long len)
{
char key[] = "X02$B:";
ULONG crypt_ptr;
long x;
for(crypt_ptr=0,x=0;x<len;x++)
{
data[x] ^= key[crypt_ptr];
if(crypt_ptr < (sizeof(key) - 2))
key[crypt_ptr] += key[crypt_ptr + 1];
else
key[crypt_ptr] += key[0];
if(!key[crypt_ptr])
key[crypt_ptr] += (char) 1;
if(++crypt_ptr >= sizeof(key) - 1)
crypt_ptr = 0;
}
}
Java代码(如果重要的话,它在Android平台上运行):
public static void Crypt(byte[] data,int offset,int len)
{
// EDIT: Changing this to byte[] instead of char[] seems to have fixed code
//char[] key = {'X','0','2','$','B',':'};
byte[] key = {'X','0','2','$','B',':'};
int size_of_key = 7;
int crypt_ptr;
int x;
for(crypt_ptr=0,x=0;x<len;x++)
{
data[x+offset] ^= key[crypt_ptr];
if(crypt_ptr < (size_of_key - 2))
key[crypt_ptr] += key[crypt_ptr + 1];
else
key[crypt_ptr] += key[0];
if(key[crypt_ptr] == 0)
key[crypt_ptr] += (char) 1;
if(++crypt_ptr >= size_of_key - 1)
crypt_ptr = 0;
}
}
我已经确认进入每个函数的数据是相同的,对于Java版本,我传递的是字节数组中正确的偏移值。如上所述,它有时会起作用,所以我不认为这是一个重大/明显的问题,更像是签名与无符号值之间的一些小问题。如果它有帮助,那么不同的第一个字节是数据中的字节125(索引124,如果从零开始)。我没有看到一个模式,就像每125个字节一样,之后几乎是随机的。数据只有171个字节,如果需要,我可以弄清楚如何作为附件发布,但我认为不是。
答案 0 :(得分:6)
我想这是因为char在java中是16位的。因此,当您递增键key[crypt_ptr] += (char) 1
或添加两个字符key[crypt_ptr] += key[crypt_ptr + 1]
时,它的作用方式与c不同(其中char为8位)。
尝试在任何地方使用字节而不是字符,只需使用符号代码进行初始化。
答案 1 :(得分:0)
您的键值必须是8位。尝试
byte[] key = "X02$B:".getBytes();
答案 2 :(得分:-1)
为什么不向我们展示差异表现出来的例子?
顺便说一句,我会写:char[] key = {'X','0','2','$','B',':', '\0'};