java byte数组异或校验时出现负数问题

简介

最近由于需要对接校园的刷卡机支付,协议需要用到异或校验。参照校验的流程对相邻数组进行异或,得出的结果却与示例的不一样,而且还是负数。
起先以为自己的算法或者数据有问题,但是检查了一遍后还是一样。

分析原因

由于协议中有字段表示的数值大于127,如协议中该字段16进制为0XA2,本来数值应该是162,结果转变成byte时变成了-94,异或校验后该字段的数值变为了负数,导致异或校验的结果不正确,这是因为java中的byte是有符号位的byte,这点和c++不一样,因此可表示的数据为-127~127(最高位为符号位)。知道了原因,剩下的就是问题的解决了。

解决方法

既然是数值太大导致byte溢出了,那么只要解决溢出的问题就好了。在这里我们只关心校验的结果,因此把byte用int类型来表示就能解决数值的问题了。
可以将异或的结果使用int类型表示(这是为了防止结果出现负数),在异或的过程中,将溢出的byte数据(即数值超出127的)通过&0xff将符号为变成正数,同时由于byte保存不了变为正数的数据,需要分配一个临时变量来保存并参与运算。

以下为解决的代码:

/** 获取指令异或值
     * @param datas
     * @return
     */
    private int getXOR(byte[] datas) {
        int temp = datas[1];              // 此处首位取1是因为本协议中第一个数据不参数异或校验,转为int防止结果出现溢出变成负数

        for (int i = 2; i < datas.length; i++) {
            int preTemp = temp;
            int iData;
            if (datas[i] < 0) {
                iData = datas[i] & 0xff;      // 变为正数计算
            } else {
                iData = datas[i];
            }
            if (temp < 0) {
                temp = temp & 0xff;          // 变为正数
            }
            temp ^= iData;

            System.out.println(preTemp + "异或" + iData + "=" + temp);
        }

        return temp;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值