2016-05-14 1 views
3

Meine Android-Anwendung empfängt ein Array von Datenbytes, die von einer C# -Anwendung gesendet wird. Ich muss diese Bytes interpretieren.Wie interpretiere ich Hex-Zahl Byte-Array von Linksverschiebung binäre Summe?

In C# -Anwendung gibt es 16 Kontrollkästchen (Bit0 bis Bit15) in Form und der Code zeigt die Verarbeitung dieser Kontrollkästchen Ergebnis.

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 an die Funktion übergeben unten beschrieben, und dann wird es zu meinem Android-Anwendung gesendet.

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

In Android-Anwendung, werden die Daten als ein Feld von 4 Bytes empfangen, und dann wird es umgewandelt in Dezimalzahlen

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

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

zum Beispiel sagen lassen, wenn Bit13 in der C# Anwendung überprüft wurde; die Andriod app empfängt ein Array von 4 Bytes, die Hexadezimalzahlen darstellt:

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

Es bis 0020 umgewandelt wird, und es wird dann in Dezimalzahlen umgewandelt:

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

Ich brauche 32 parsen Bit13 herauszufinden wurde ausgewählt. Bit13 ist nur ein Beispiel für 32. Ich muss herausfinden, welches oder mehrere Bit (0 bis 15) ausgewählt sind.

+1

Warum erhalten Sie die Daten als ein Array von 4 Bytes statt 2 Bytes? – user0815

+1

Warum multiplizieren Sie mit 8? Wenn Sie zwei Bytes haben, dann Daten [0] << 8 + Daten [1] zu einem int16 zu bilden. Dann durchläuft Ihre for-Schleife 16 Bits und sieht aus wie die Umkehrung des Flag-Codes. – jdweng

+1

@JornVernee er fügt 2 Bytes hinzu (0 und 1) - aber ich bekomme nicht den ganzen Prozess der Konvertierung ... – user0815

Antwort

2

Um zu überprüfen, ob ein Bit gesetzt ist, können Sie ein bitweises UND mit diesem Bit ausführen. Überprüfen Sie dann, ob das Ergebnis gleich 0 ist. Wenn dies nicht der Fall ist, wurde das Bit gesetzt.

z.B.

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

A char ist unsigned 16 Bit, so dass Sie das Speichern des Ergebnisses nutzen könnten.

0020 ist fast richtig, aber die Bytes sind umgekehrt (00 20, sollte 20 00 für Bit13 sein).

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 

Sie können diese Methode verwenden, um jedes Bit zu überprüfen. Ersetzen Sie einfach die durch den Index, den Sie überprüfen möchten.


Ich bin mit einem char hier, da dies ein wenig schöner gedruckt wird. Sie könnten eine short verwenden, aber wann immer Sie das in eine int konvertieren (was implizit passieren kann), wird der Wert mit 1 aufgefüllt, wenn das höchstwertige Bit gesetzt wurde, weil es ein signierter Typ ist. char ist unsigned jedoch, so hat es dieses Verhalten nicht.

+0

Gemäß meinem Beispiel '0x30 0x30 0x32 0x30' ist Bit13 das einzige Bit, das gesetzt wird. Warum sind viele Bits in Ihrem Ergebnis "1"? – Sithu

+0

@Sithu Es war nur ein Beispiel ... aber ich habe endlich herausgefunden, wie deine Konvertierung funktionieren soll. Siehe aktualisierte Antwort. –

+0

Danke. Das funktioniert fast. Wenn ich jedoch alle Bits einschalte, ist der Wert "FFFF" äquivalent zu "0x46 0x46 0x46 0x46" und es wird 'java.lang.NumberFormatException: Wert außerhalb des Bereichs ausgegeben. Wert: "FFFF" Radix: 16 at java.lang.Short.parseShort (Unbekannte Quelle) '. Der gleiche Fehler für "FF7F", wenn alle Bits außer Bit15 ausgeschaltet sind. – Sithu

Verwandte Themen