1. 程式人生 > >java byte陣列異或校驗時出現負數問題

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; }