# HEX -> DEC -> ASCII ... falsches Encoding?



## TobiGuest (3. Jun 2011)

Hallo zusammen,

ich versuche zur Zeit eine *.hex Datei einzulesen und diese Daten dann über TCP zu versenden.
Soweit eigentlich ganz einfach.
Nur komme ich mit dem ASCII encoding nicht ganz klar. Um zb. ein "AB" (hex) aus der hex Datei richtig zu senden, muss ich diese zuerst in eine Zahl umwandeln und dann daraus einen neuen ASCII Code erzeugen damit diese richtig bei meinem Empfänger ankommen (AVR)

Dies funktioniert nur teilweise und ich weis nicht wieso.

Beispiel:

Ausschnitt hex Datei:

0F931F93182F062F0E94863A812F806A

nun lese ich mit Hilfe eines Java Codes die Hex Sequenz Byteweis ein (also "0F" "93"...)

->


```
for(int i=0;i<s.length();i+=2){
    		  byte[] b = { (byte)Integer.valueOf(s.substring(i, i+2), 16).intValue() };    		  
    		  //Charset charset = Charset.forName("US-ASCII");
         x += new String(b); 
    		  //x += new String(b,charset);    	

   toSend.append(x);	  
       	  }
```

wenn ich nun den String x mit Hilfe von TCP sende ... folgender Code (aufs Wesentliche zusammenkopiert):


```
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
out.write(toSend.toString());
```

dann funktioniert das auch soweit.
Nur das der Hex Code 81 (viert letztes Byte in obiger Sequenz) falsch gesendet wird. Hier wird keine 0x81 gesendet sondern eine 3F ?!?!? (ersichtlich im Wireshark)

Ich kann mit nicht erklären wieso alles richtig gesendet wird nur das nicht.
Ich vermute es liegt irgendwie am Encoding... habe wie oben ersichtlich in Kommentar (charset) auch schon andere versucht, jedoch hilft das alles nicht. 
Auffällig ist, das immer wenn ein Zeichen nicht unterstützt wird, eine "3F" gesendet wird?!? Wieso das??? Sicherlich ist das irgenwo so spezifiziert nur finde ich dazu nichts und weis auch nicht wonach ich wirklich suchen soll.

Kann mir jemand einen Tip geben an welcher Stelle ich drehen muss damit alle Werte richtig interpretiert werden?

Vielen Dank,

Tobi


----------



## HoaX (3. Jun 2011)

Binärdaten schickt man nunmal nicht per Writer. Benutz direkt den OutputStream, der kann dann auch direkt einen int versenden.


----------



## TobiGuest (3. Jun 2011)

juhuuu das wars... danke dir!!! 

So einfach kanns sein.. der Outputstream nimmt ja dann auch direkt die byte Daten... 
oh man ich blick da nie durch mit den ganzen Streams irgendwie 

danke dir HoaX!!!


----------



## HoaX (3. Jun 2011)

Is doch ganz einfach:
Streams -> Binärdaten, die Daten bleiben mit Sicherheit so wie sie sind
Reader/Writer -> Stringdaten, d.h. Encoding usw wird versucht umzuwandeln -> ändert ggf. Daten


----------



## tagedieb (4. Jun 2011)

Anmerkung: Am besten benutzt du DataOutput- und DataInputStreams.

Java benutzt 'signed' bytes mit einen Wertebereich von -128 bis +127; also nicht wie man annehmen koennte 0 bis 255
Willst du eine byte in eine Dezimalzahl zurueckwandeln reicht ein cast nicht mehr aus. In diesem Fall musst du den bit operator 'and' verwenden.


```
// int/hex zahl
  int i = 0x81;
  // to byte
  byte b = (byte) i;
  // back to int
  int j = b & 0xff;
  System.out.println(j);
```


----------



## TobiGuest (4. Jun 2011)

Morgen zusammen,

@HoaX: danke für die Aufklärung. Werde mir das so merken und möglichst immer Streams nutzen!

@tagedieb: du meinst also das die 0x81 auch richtig gesendet würde wenn ich das mit dem & 0xff gemacht hätte? Muss ich mal versuchen

Danke!!


----------



## tagedieb (4. Jun 2011)

NEIN. 


```
& 0xff
```
 benoetigst du um ein byte in einen int zurueckzuverwandeln.

Deine urspruengliche Loesung wuerde wohl funktionieren, wenn du den HEX Wert in ein char anstatt ein byte castest. Aber wieso nicht gleich den original HEX String senden?

Fuer die Uebertragung sollten aber bytes verwendet werden um platz zu sparen.


----------

