2014-01-09 69 views
1

我有一個64字節的數組。我從UsbConnection.bulkTRansfer()收到64字節的數據。我想檢查我是否收到「同步」數據包。 「同步」是一個很長的值,其值爲4006390527l。這是我的代碼。如何在java中比較64字節數組的內容?

byte[] buffer = new byte[64]; 
bytesReceived += usbConnection.bulkTransfer(usbEndpointIn, buffer, 64, 2000); 

String l=Base64.encodeToString(buffer,0); 
long ll=Long.parseLong(l); 

if(C.SYNC_PAD_TO_HOST == ll) { 
Log.d(TAG,"SyncReceived");//This is the Sync 
gotSync=true; 
System.arraycopy(buffer, 0, rcvbuf, 0, buffer.length); 
} 

我越來越奇怪的結果。 if條件不會成立。這裏有什麼問題。

+2

'Sync'聽起來更像是一個64位** **價值... –

+1

64個字節是遠遠超過可容納在'long'。請告訴我們這些64字節是什麼。 –

+0

我會嘗試猜...你想讀取64個字節,並且如果第一個字節是0xEECCAAFF,你有* Sync *嗎? –

回答

0

這裏有幾個問題。全速USB-Sync是32位。 int能夠包含數據,但不能作爲無符號整數。您的代碼將其存儲爲long的唯一原因是將0x800000000xFFFFFFFF的值存儲爲正數。但是,僅使用long的最低有效32位。

爲了計算流中的第一小尾數32位無符號數,並將其存儲爲long,使用:

long ll = (buffer[0] & 0xFF) 
     | ((buffer[1] & 0xFF) << 8) 
     | ((buffer[2] & 0xFF) << 16) 
     | ((buffer[3] & 0xFFL) << 24); 

這裏發生的事情的細目:

你在同步數據包十六進制是0x17E1444C。 USB使用little-endian傳輸此值,這意味着最低有效字節首先被髮送。在電線,字節來順序如下:

4C 44 17 E1

要擊穿步驟:

long ll = buffer[0] & 0xFF; 
// ll == 0x4C & 0x000000FF 
// == (long) 0x0000004C 
// == 0x000000000000004C 

ll |= (buffer[1] && 0xFF) << 8; 
// ll == 0x000000000000004C | ((0x44 & 0x000000FF) << 8) 
// == 0x000000000000004C | (0x00000044 << 8) 
// == 0x000000000000004C | 0x00004400 
// == 0x000000000000004C | (long) 0x00004400 
// == 0x000000000000004C | 0x0000000000004400 
// == 0x000000000000004C 

ll |= (buffer[2] & 0xFF) << 16; 
// ll == 0x000000000000444C | ((0xE1 & 0x000000FF) << 16) 
// == 0x000000000000444C | (0x000000E1 << 16) 
// == 0x000000000000444C | 0x00E10000 
// == 0x000000000000444C | (long) 0x00E10000 
// == 0x000000000000444C | 0x0000000000E10000 
// == 0x0000000000E1444C 

這最後列入說明了爲什麼我們使用& 0xFF。如果不使用此位與運算,這裏不使用& 0xFF會發生什麼:

ll |= buffer[2] << 16; 
// ll == 0x000000000000444C | ((int) 0xE1) << 16) 
// == 0x000000000000444C | (0xFFFFFFE1 << 16) 
// == 0x000000000000444C | 0xFFE10000 
// == 0x000000000000444C | (long) 0xFFE10000 
// == 0x000000000000444C | 0xFFFFFFFFFFE10000 
// == 0xFFFFFFFFFFE1444C 

這是因爲E1超過最大正byte0x7F),因此它爲負數處理。直接投射到int時,負號被保留。爲了避免這種行爲,我們使用完整的8位AND將其轉換爲int

現在回到過程。最後一個字節:

ll |= (buffer[3] & 0xFFL) << 24; 
// ll == 0x0000000000E1444C | ((0x17 & 0x00000000000000FF) << 24) 
// == 0x0000000000E1444C | (0x0000000000000017 << 24) 
// == 0x0000000000E1444C | 0x0000000017000000 
// == 0x0000000017E1444C 

你會發現過去的按位與使用long版本的0xFF以上進行。這是因爲如果最低有效字節超過最大正字節(0x7F),則24位(或更高)的左移有可能產生負的int。想象一下,而不是17,最後一個字節是A7。下面是使用使用& 0xFF,而不是& 0xFFL時會發生什麼:

ll |= (buffer[3] & 0xFF) << 24; 
// ll == 0x0000000000E1444C | ((0xA7 & 0x000000FF) << 24) 
// == 0x0000000000E1444C | (0x000000A7 << 24) 
// == 0x0000000000E1444C | 0xA7000000 
// == 0x0000000000E1444C | (long) 0xA7000000 
// == 0x0000000000E1444C | 0xFFFFFFA7000000 
// == 0xFFFFFFFFA7E1444C