最近调试协议要求计算校验和,描述为:
校验和为16进制字符(0-F)表示的32位整数(8Byte)。
计算方法为:对“消息头+会话头+事务头+操作信息”按32位异或,对异或结果取反后的值为校验和。按上面意思,在网上查了一遍后,理解意思为:将“消息头+会话头+事务头+操作信息”拼成一个长字符串,然后按32长度分组,第一组和第二组异或,结果和第三组异或.......最后结果取反,再转成16进制。问题来了:
1、不是很确定上面计算思路是否正确
2、java中对字符串进行异或如何来操作?事情紧急,困扰好几天了!请高手们来看看!
校验和为16进制字符(0-F)表示的32位整数(8Byte)。
计算方法为:对“消息头+会话头+事务头+操作信息”按32位异或,对异或结果取反后的值为校验和。按上面意思,在网上查了一遍后,理解意思为:将“消息头+会话头+事务头+操作信息”拼成一个长字符串,然后按32长度分组,第一组和第二组异或,结果和第三组异或.......最后结果取反,再转成16进制。问题来了:
1、不是很确定上面计算思路是否正确
2、java中对字符串进行异或如何来操作?事情紧急,困扰好几天了!请高手们来看看!
你的意思是,将拼成的字符串直接转成byte[],然后byte[0]^byte[32]^byte[64]这样异或,
最后得出来的结果也是byte[]的,长度为32
对“4个字节为单元异或”不明白。你是说:前4个字节和后4个字节进行异或?依次类推?
int b1=0;
int b2=0;
int b3=0;
int b4=0;
for(int i=0;i<buf.length;i+=4){
byte tb1=i>=buf.length?0:buf[i];
byte tb2=i+1>=buf.length?0:buf[i+1];
byte tb3=i+2>=buf.length?0:buf[i+2];
byte tb4=i+3>=buf.length?0:buf[i+3];
b1=b1^tb1;
b2=b2^tb2;
b3=b3^tb3;
b4=b4^tb4;
}
System.out.println("0x"+Integer.toHexString(b1));
System.out.println("0x"+Integer.toHexString(b2));
System.out.println("0x"+Integer.toHexString(b3));
System.out.println("0x"+Integer.toHexString(b4));
}
public static void main(String[] args) {
byte buf[]=new byte[0xa];
for(int i=0;i<0xa;i++){
buf[i]=(byte)i;
}
test(buf);
}
byte[] b=arr;
if(arr.length%4!=0){
b=new byte[(arr.length/4+1)<<2];
System.arraycopy(arr,0,b,0,arr.length);
}
int ret=0;
for(int i=0;i<b.length/4;i++){
int n=b[i+3];
n|=b[i+2]<<8;
n|=b[i+1]<<16;
n|=b[i]<<24;
ret^=n;
}
return ret;
}
因为调试的协议是通过TCP SOCKET传输数据,如果最后8字节长度的校验和不正确,对方就收不到我过去的消息指令。
{
int i;
memset(res, 0, 8);
for(i=0; i<len; i+=4)
{
res[0]^=(buf+i)[0];
res[1]^=(buf+i)[1];
res[2]^=(buf+i)[2];
res[3]^=(buf+i)[3];
}; res[0]=~res[0];
res[1]=~res[1];
res[2]=~res[2];
res[3]=~res[3]; // 将16进制数扩展为对应字符串(如0xE8--->"E8")
for(i = MSG_CHKSUM_LEN-1; i >= 0; i --)
{
if ( i % 2 ) // LOW
{
res[i] = (res[i/2] & 0x0F) + '0';
if ( res[i] > '9' )
{
res[i] = res[i] + 'A' - '0' - 10;
}
}
else // HIGH
{
res[i] = ((res[i/2] >> 4) & 0x0F) + '0';
if ( res[i] > '9' )
{
res[i] = res[i] + 'A' - '0' - 10;
}
}
}
}
这是C的实现,转成JAVA如何来写呢?