最近调试协议要求计算校验和,描述为:
校验和为16进制字符(0-F)表示的32位整数(8Byte)。
计算方法为:对“消息头+会话头+事务头+操作信息”按32位异或,对异或结果取反后的值为校验和。按上面意思,在网上查了一遍后,理解意思为:将“消息头+会话头+事务头+操作信息”拼成一个长字符串,然后按32长度分组,第一组和第二组异或,结果和第三组异或.......最后结果取反,再转成16进制。问题来了:
1、不是很确定上面计算思路是否正确
2、java中对字符串进行异或如何来操作?事情紧急,困扰好几天了!请高手们来看看!

解决方案 »

  1.   

    我不清楚具体怎么操作,不过听你的解释因该不是对字符串操作你不要把它们变成String,直接对byte[]操作来校验.
      

  2.   

    fool_leave(请及时结贴) :
        你的意思是,将拼成的字符串直接转成byte[],然后byte[0]^byte[32]^byte[64]这样异或,
    最后得出来的结果也是byte[]的,长度为32
      

  3.   

    treeroot(旗鲁特) :能否再说详细点?能否给点代码?
    对“4个字节为单元异或”不明白。你是说:前4个字节和后4个字节进行异或?依次类推?
      

  4.   

    按照要求,那应该是前32个字节和后32个字节异或,然后结果再和后32个字节异或,fool_leave(请及时结贴) 是这样理解的。
      

  5.   

    你说的是这个意思吗  public static void test(byte buf[]){
        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);
      }
      

  6.   

    public static int checkSum(byte[] arr){
            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;        
        }
      

  7.   

    感谢 fool_leave(请及时结贴) treeroot(旗鲁特) 的帮助我再试试看计算出来数值对不对。
    因为调试的协议是通过TCP SOCKET传输数据,如果最后8字节长度的校验和不正确,对方就收不到我过去的消息指令。
      

  8.   

    ChkSum(int len, char* buf, char* res)
    {
        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如何来写呢?