2016-05-14 66 views
3

我的android應用程序正在接收從C#應用程序發送的數據字節數組。我需要解釋這些字節。如何從左移二進制和解釋十六進制數字節數組?

在C#應用程序中,表單中有16個複選框(Bit0到Bit15),代碼顯示這些複選框結果的處理。

ushort flag = (ushort)(
       (Bit0.Checked ? (1 << 0) : (0)) + 
       (Bit1.Checked ? (1 << 1) : (0)) + 
       (Bit2.Checked ? (1 << 2) : (0)) + 
       (Bit3.Checked ? (1 << 3) : (0)) + 
       (Bit4.Checked ? (1 << 4) : (0)) + 
       (Bit5.Checked ? (1 << 5) : (0)) + 
       (Bit6.Checked ? (1 << 6) : (0)) + 
       (Bit7.Checked ? (1 << 7) : (0)) + 
       (Bit8.Checked ? (1 << 8) : (0)) + 
       (Bit9.Checked ? (1 << 9) : (0)) + 
       (Bit10.Checked ? (1 << 10) : (0)) + 
       (Bit11.Checked ? (1 << 11) : (0)) + 
       (Bit12.Checked ? (1 << 12) : (0)) + 
       (Bit13.Checked ? (1 << 13) : (0)) + 
       (Bit14.Checked ? (1 << 14) : (0)) + 
       (Bit15.Checked ? (1 << 15) : (0))); 

flag傳遞給下面描述的功能,然後將其發送到我的Android應用程序。

public static void setFlag(List<Byte> data, ushort flag) 
    { 
     for (int i = 0; i < 2; i++) 
     { 
      int t = flag >> (i * 8); 
      data.Add((byte)(t & 0x00FF)); 
     } 
    } 

在Android應用,該數據被接收到的爲4個字節的數組,然後將其轉換爲十進制

public String bytesToAscii(byte[] data) { 
    String str = new String(data); 
    return str.trim(); 
} 

// This returns the decimal 
Integer.parseInt(bytesToAscii(flag), 16) 

比方說,例如,當位13在C#申請被檢查;安卓應用接收的4個字節的數組表示十六進制數:

flag[0] = 0x30; 
flag[1] = 0x30; 
flag[2] = 0x32; 
flag[3] = 0x30; 

它被轉換爲0020,然後將其轉換爲十進制:

Integer.parseInt(bytesToAscii(flag), 16); // 32 

我需要解析32找出位13被選中。 Bit13只是32的一個例子。我需要確定選擇了哪一個或多個Bit(0到15)。

+1

爲什麼你收到的數據是4字節而不是2字節的數組? – user0815

+1

你爲什麼乘以8?如果你有兩個字節,那麼data [0] << 8 + data [1]組成一個int16。然後你的循環通過16位循環,看起來像'旗'代碼的反面。 – jdweng

+1

@JornVernee他加了2 Bytes(0和1) - 但我沒有得到轉換的整個過程... – user0815

回答

2

要檢查是否設置了一位,可以對該位執行按位與操作。然後檢查結果是否等於0.如果不是,則該位被設置。

例如

00100110 
00000010  // checks the second bit 
-------- & 
00000010  // result != 0, so the bit was set 

一個char是無符號的16位,所以你可以用它來存儲結果。

0020幾乎是正確的,但字節相反(00 20,應爲20 00爲Bit13)。

byte[] flag = new byte[4];  
flag[0] = 0x30; 
flag[1] = 0x30; 
flag[2] = 0x32; 
flag[3] = 0x30; 

// Bytes to char, using the 'oversized' short so the numbers won't be out of range 
short b1 = Short.parseShort(new String(new byte[]{flag[0], flag[1]}), 16); 
short b2 = Short.parseShort(new String(new byte[]{flag[2], flag[3]}), 16); 
char i = (char) (b1 | (b2 << 8)); 

// Print contents as binary string 
System.out.println(String.format("%16s", Integer.toBinaryString(i)).replace(' ', '0')); 

// Output: 0010000000000000 

// Check if 14'th bit is set (at index 13) 
boolean isSet = ((i & (1 << 13)) != 0); 

System.out.println(isSet); // true 

您可以使用該方法檢查每一位。只需將13替換爲您要檢查的索引即可。


我使用的是char在這裏,因爲這將打印更好一點。您可以使用short,但每當您將其轉換爲int(可能會隱式發生)時,如果設置了最高有效位,則會使用1填充值,因爲這是簽署的類型。 char但是沒有簽名,所以它沒有這種行爲。

+0

根據我的示例'0x30 0x30 0x32 0x30',唯一設置的位是Bit13。爲什麼在結果中有很多位是'1'? – Sithu

+0

@Sithu這只是一個例子......但我終於想出了你的轉換應該如何工作。查看更新的答案。 –

+0

謝謝。這幾乎奏效。但是,當我打開所有位時,該值爲'FFFF',相當於0x46 0x46 0x46 0x46,它會拋出java.lang.NumberFormatException:值超出範圍。值:「FFFF」基數:16在java.lang.Short.parseShort(未知源)'。當Bit15以外的所有位都關閉時,'FF7F'的錯誤同樣出現。 – Sithu

相關問題