String von base64 nach Ansi und dann nach Integer - geht nicht?

  • Antworten:22
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 690

29.03.2016, 21:50:57 via Website

Hallo,

ein Gateway für eine Heizungssteuerung liefert mir einen base64-codierten String. Aus diesem String möchte ich einen Zahlenwert (Integer) extrahieren (später dann noch weitere Werte, aber erstmal muss es mit diesem einen Wert funktionieren). Dazu hab ich folgendes Code-Fragment:

byte[] DecodedBytes = Base64.decode(DataString,Base64.NO_WRAP);
String DecodedString = new String(DecodedBytes,"US-ASCII");
// die ersten beiden Zeichen im String sind unwichtig
DecodedString = DecodedString.substring(2,DecodedString.length());
String RaumCount = DecodedString.substring(0,1);
CubeMMsg_RoomCount = parseInt(RaumCount);  // CubeMMsg_RoomCount ist an anderer Stelle als int deklariert

Allerdings erhalte ich genau bei parseInteine Exception.
EDIT: Die Exception lautet: "java.lang.NumberFormatException: Invalid int: "\u0005""

Im Debugger sieht der Inhalt von DecodedString so aus wie im angehängten Bild (copy&paste entfernt leider Zeichen)
User uploaded photo

Jetzt ist für mich die Frage: Kann ich die Konvertierung von base64 nach String irgendwie beeinflussen? Oder brauch ich statt parseInt etwas anderes? Was?

Danke und Gruss
G.-U.M.

— geändert am 29.03.2016, 21:58:37

N'y pas n'y
tu car tu
mal tu mal

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.165

29.03.2016, 21:55:58 via Website

Weisst du sucher das es US-ASCII ist?
ich würde mal standard urf-8 benutzen und testen was rauskommt.

Die Formatierungen /u005 etc. sehen nach irgend einem "Container" aus indem irgendwelche eichen escaped werden.
Ist dein String irgenwie json formatiert o.ä.?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 690

29.03.2016, 22:12:21 via Website

Hallo,

Pascal P.

Weisst du sucher das es US-ASCII ist?

Nein, weiß ich nicht sicher. Aber es sieht für mich erstmal so aus

ich würde mal standard urf-8 benutzen und testen was rauskommt.

Das hab ich eben getan. Leider ändert sich nichts.

Die Formatierungen /u005 etc. sehen nach irgend einem "Container" aus indem irgendwelche eichen escaped werden.
Ist dein String irgenwie json formatiert o.ä.?

Da sind eigentlich überhaupt keine Formatierungen. Das ganze geht (vereinfacht beschrieben) so:
Aufbau einer TCP-Verbindung auf Port 62910 (das ist der Port, auf dem das Gateway wartet).
Bei Zustandekommen einer Verbindung gibt das Gateway u.a. die abgebildete Zeile aus (ich hab das ganze erst mit einem Lazarus-/Pascal-Programm ausprobiert und da sieht die Zeile so aus (noch vor dem Entfernen der beiden ersten Zeichen):

User uploaded photo

Ich denke, es ist klar zu sehen, dass das ganz anders aussieht. Nun arbeitet, so weit ich weiß, Lazarus nicht mit UTF-8 sondern mit Ansi-Strings. Wobei das ja grundsätzlich kein Problem sein sollte, sofern die Konvertierungsroutinen für String-nach-Integer funktionieren.

Danke und Gruss
G.-U.M.

N'y pas n'y
tu car tu
mal tu mal

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.165

29.03.2016, 22:24:20 via Website

Ich würde nochmal verschiedene Zeichensätze durchprobieren obs passt.
Oder versuch mal das hier, eigentlcih wie du nur andere APrameter:

byte[] data = Base64.decode(base64, Base64.DEFAULT);

String text = new String(data, "UTF-8");

Sonst wie sieht denn deine Methode parseInt aus und was für eine Exception bekommst du?
Zudem wenn ich deinen Code und den String in zusammenhang nehme willst du das 3. Zeichen als int. Durch die /u005 etc. wäre das 3. Zeichen eine 0.

— geändert am 29.03.2016, 22:24:41

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 8.173

29.03.2016, 22:37:47 via Website

Was soll parseInt denn auch mit \u0005 usw anfangen? Das braucht als Input einen String, ASCII-Zeichen und keine binären Daten!

if all else fails, read the instructions.

Antworten
  • Forum-Beiträge: 690

30.03.2016, 07:17:00 via Website

Pascal P.

Ich würde nochmal verschiedene Zeichensätze durchprobieren obs passt.
Oder versuch mal das hier, eigentlcih wie du nur andere APrameter:

byte[] data = Base64.decode(base64, Base64.DEFAULT);

String text = new String(data, "UTF-8");

Das war die erste Variante - über die bin ich erst drauf gekommen, dass es verschiedene Möglichkeiten geben könnte. Leider ohne Erfolg.

Sonst wie sieht denn deine Methode parseInt aus und was für eine Exception bekommst du?

parseInt ist die normale Integer.parseInt (ich hab den Verweis auf Integer nur bei den Imports hinzugefügt). #

Zudem wenn ich deinen Code und den String in zusammenhang nehme willst du das 3. Zeichen als int. Durch die /u005 etc. wäre das 3. Zeichen eine 0.

Das unterstützt meine (über Nacht bzw. über den Post vom "Klaus T.") gewachsene Vermutung, dass ich zwar einen String hab, aber sich meine POsitionen in diesem String komplett geändert haben. Ich war bisher davon ausgegangen, dass z.B. das "\u0005" ein einzelnes Zeichen darstellt. Daher auch die Vermutung mit dem Unicode.
Da muss ich nochmal genauer nachgucken und ausprobieren.
Dankeschön.
Gruss
G.-U.M.

N'y pas n'y
tu car tu
mal tu mal

Antworten
  • Forum-Beiträge: 690

30.03.2016, 07:17:56 via Website

Klaus T.

Was soll parseInt denn auch mit \u0005 usw anfangen? Das braucht als Input einen String, ASCII-Zeichen und keine binären Daten!

Dankeschön, du hast mich da auf eine Idee gebracht. Details siehe bitte meine Antwort von heute an "Pascal P.".

Gruss
G.-U.M.

N'y pas n'y
tu car tu
mal tu mal

Antworten
  • Forum-Beiträge: 690

30.03.2016, 08:01:20 via Website

Gerd-Ulrich M.

Pascal P.

Ich würde nochmal verschiedene Zeichensätze durchprobieren obs passt.
Oder versuch mal das hier, eigentlcih wie du nur andere APrameter:

byte[] data = Base64.decode(base64, Base64.DEFAULT);

String text = new String(data, "UTF-8");

Das war die erste Variante - über die bin ich erst drauf gekommen, dass es verschiedene Möglichkeiten geben könnte. Leider ohne Erfolg.

Sonst wie sieht denn deine Methode parseInt aus und was für eine Exception bekommst du?

parseInt ist die normale Integer.parseInt (ich hab den Verweis auf Integer nur bei den Imports hinzugefügt). #

Zudem wenn ich deinen Code und den String in zusammenhang nehme willst du das 3. Zeichen als int. Durch die /u005 etc. wäre das 3. Zeichen eine 0.

Das unterstützt meine (über Nacht bzw. über den Post vom "Klaus T.") gewachsene Vermutung, dass ich zwar einen String hab, aber sich meine POsitionen in diesem String komplett geändert haben. Ich war bisher davon ausgegangen, dass z.B. das "\u0005" ein einzelnes Zeichen darstellt. Daher auch die Vermutung mit dem Unicode.
Da muss ich nochmal genauer nachgucken und ausprobieren.
Dankeschön.
Gruss
G.-U.M.

EDIT: Ich habs mir eben noch schnell (vor der ARbeit) angeguckt. Da es am einfachsten war, hab ich 2 Screenshots gemacht, die, hoffe ich, das wesentliche zeigen. Vorab: Es ist noch nicht gelöst.

So sieht das ganze aus, wenn ich bis zum Haltepunkt debugge. User uploaded photo
Die entscheidene Variable ist "DecodedString". (Die vielen auskommentierten Codezeilen (sowie vielleicht auch der gesamte Stil) bitte nicht unbedingt bewerten).
Nach den Hinweisen hab ich bereits die Parameter für substring angepasst - da steht eine, meiner Meinung nach, gültige "5" an der Stelle.
Allerdings, wenn ich nun die Zeile ausführen lassen, erhalte ich nach wie vor die Exception.
User uploaded photo
Ich hab keine Ahnung, was da falsch ist - hab ich nen grundsätzlichen Denkfehler?

Danke und Gruss
G.-U.M.

N'y pas n'y
tu car tu
mal tu mal

Antworten
  • Forum-Beiträge: 8.173

30.03.2016, 08:12:18 via Website

Kann es sein, dass du meinst, das \u0005 wären mehrere Zeichen? Das ist ein binäres Zeichen und mit deinem substr zielst du mitten ins "Wohnzimmer" und das gibt dann die Exception....würde ich jetzt auf den schnellen Blick sagen.

Guck dir RaumCount beim Tracen mal an, mMn ist da das "h" drin....

— geändert am 30.03.2016, 08:19:32

if all else fails, read the instructions.

Antworten
  • Forum-Beiträge: 690

30.03.2016, 08:47:38 via Website

Klaus T.

Kann es sein, dass du meinst, das \u0005 wären mehrere Zeichen? Das ist ein binäres Zeichen und mit deinem substr zielst du mitten ins "Wohnzimmer" und das gibt dann die Exception....würde ich jetzt auf den schnellen Blick sagen.

Nunja, zuerst hatte ich gedacht, dass das \u0005 ein einziges Zeichen wäre und das substr dieses auch so interpretiert (deshalb noch die Quelltextzeile mit substr(0,1)).

Guck dir RaumCount beim Tracen mal an, mMn ist da das "h" drin....

Mach ich frühestens heute abend (vorher komme ich nicht dazu).

Aber: Wenn es ein binäres Zeichen ist, welche Methode/Funktion liefert mir denn dann das Zeichen und lässt es mich in einen Integer-Wert konvertieren? Da fehlt mir noch Wissen (das Projekt mache ich ja nicht nur wegen der Heizungsteuerung, sondern auch um zu lernen)

Danke und Gruss

G.-U.M.

N'y pas n'y
tu car tu
mal tu mal

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.165

30.03.2016, 11:11:47 via Website

Wie lang ist denn der Base64 string?
Vielleicht pstest du den mal hier, dann könnte ich mal schaen, was ich da rausbekomme.
Ich vermute dass es nur irgend ein Zeichensatzproblem o.ä. ist.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 690

30.03.2016, 11:21:38 via Website

Pascal P.

Wie lang ist denn der Base64 string?

Müsste ich mal zählen. Allerdings ist die Länge variabel, da es sich nur um einen Teil einer längeren TCP-Message handelt.

Vielleicht pstest du den mal hier, dann könnte ich mal schaen, was ich da rausbekomme.

Ich habe schon überlegt, ob ich doch mal das ganze Projekt hier einstelle - allerdings reicht die Java-Seite dafür nicht aus. Ich müsste auch den Gateway-Ersatz (den hab ich geschrieben, damit ich klare und reproduzierbare Werte erhalte) mit liefern und den erstmal so aufbessern, dass er unabhängig von meinem PC (fest eincompilierte IP-Adresse) läuft.

Ich vermute dass es nur irgend ein Zeichensatzproblem o.ä. ist.

Das wäre schön.
Ich werde nur nicht vor heute Abend dazu kommen.

Danke und Gruss

G.-U.M.

N'y pas n'y
tu car tu
mal tu mal

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.165

30.03.2016, 11:31:03 via Website

Mir würde der Base64 string schon reichen ;)

Und lass dir Zeit, die Arbeit rennt nicht weg :P

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 690

30.03.2016, 13:21:20 via Website

Pascal P.

Mir würde der Base64 string schon reichen ;)

Gefunden. Ich hatte von den ersten Tests mit einem anderen Programm noch eine gespeicherte Version der Messages (übrigens die gleiche, die im oben eingefügten Screenshot sichtbar wird)

7QzYbQATAf9LRVEwODM3MjY4AAsABEAAAAAAAAAAAP///////////////////////////wsABEAAAAAAAAAAQf///////////////////////////2h0dHA6Ly9tYXguZXEtMy5kZTo4MC9jdWJlADAvbG9va3VwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAENFVAAACgADAAAOEENFU1QAAwACAAAcIA==

Hinweis: nach der Konvertierung von base64 sind die ersten zwei Zeichen auch noch nicht für mich wichtig.

Und lass dir Zeit, die Arbeit rennt nicht weg :P

Nein, dass nicht, aber interessieren tut's mich trotzdem.
Vielen Dank für deine Mühe.
Gruss
G.-U.M.

N'y pas n'y
tu car tu
mal tu mal

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.165

30.03.2016, 14:01:47 via Website

Irgendwie passt der bas64 string nicht.
Da sind nichtdruckbare Zeichen drin etc.
Kommt da überhaupt wieder text raus oder kann es sein dass du mit dem Typte array arbeiten musst und die eizelnen Bytes interpetieren?

Und warum steht in der Base64 diese Url drinne: https://max.eq-3.de:80/cube ?
Ist das dein endgerät?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 690

30.03.2016, 14:15:11 via Website

Pascal P.

Irgendwie passt der bas64 string nicht.
Da sind nichtdruckbare Zeichen drin etc.
Kommt da überhaupt wieder text raus oder kann es sein dass du mit dem Typte array arbeiten musst und die eizelnen Bytes interpetieren?
Laut der Beschreibung sollten da lesbare Zeichen rauskommen (siehe auch den Screenshot oben). jetzt kann es ntürlich sein, dass ich da aufgrund der Vorgeschichte (Pascal/Lazarus) der Meinung aufgesessen bin, das es wirklich ein String ist.
Falls es wirklcih ein Array ist, wäre ja einiges viel einfacher, oder?

Und warum steht in der Base64 diese Url drinne: https://max.eq-3.de:80/cube ?
Ist das dein endgerät?

Ja - kennst du das Ding?

N'y pas n'y
tu car tu
mal tu mal

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.165

30.03.2016, 14:19:44 via Website

Ne kenne ich nicht, aber das Gerät muss doch die Daten in einem gescheiten Format zurückgeben.
Steht etwas hilfreiches im Datenblatt?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 690

30.03.2016, 14:45:45 via Website

Pascal P.

Ne kenne ich nicht, aber das Gerät muss doch die Daten in einem gescheiten Format zurückgeben.
Steht etwas hilfreiches im Datenblatt?

Schön wär's. Das ganze lebt vom Ausprobieren bzw. ausprobiert-worden-sein. Der Hersteller hat keine API spezifiziert.

Aber trotzdem bist du genial: Du hast mich dazu gebracht, nochmal da nachzugucken, wo sich jemand die Mühe gemacht hat, einen Teil des Protokolls zu entschlüsseln - und da steht nix von Strings oder so. Das mit dem String war von mir, da ich mich in Pascal/Lazarus wesentlich leichter tue, aus einem String Infos zu extrahieren als aus einem Array. Und deshalb dachte ich, in Java ist das genauso.
Ok. Mein fehler - tut mir leid!

So, wenn ich jetzt das Array nehme (das ich ja als DecodesBytes schon habe): Welche Funktionen gucke ich mir an, damit ich aus einem Byte-Array einzelne Bytes extrahieren kann? Und im Hinblick auf die enthaltenen Integer-Werte: Welche Funtionen muss ich mir da angucken, um die Bytes in Integer zu konvertieren?

(nicht verraten wie's geht, ich will's lernen ;) )
Danke und Gruss
G.-U.M.

N'y pas n'y
tu car tu
mal tu mal

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.165

30.03.2016, 15:11:21 via Website

Da musst du dann die Positionen der Bytes wssen und was was bedeutet.
Dann kannst du auch bytes in integer und Strings umwandeln.
Aber ohne Protokollspezifikation beißt du dir daran die Zähne aus.
Aber kannst gerne mit binärdaten experimentieren ;)

Konvertierfunktionen findet man im Internet obwohl du da bei der Kodierung aufpassen musst ob das int direkt ins byte oder in Low und high kodiert ist.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 690

30.03.2016, 15:20:13 via Website

Pascal P.

Da musst du dann die Positionen der Bytes wssen und was was bedeutet.

OK, die weiß ich. Die Stehen in der Auflistung, die ich hab.

Dann kannst du auch bytes in integer und Strings umwandeln.
Aber ohne Protokollspezifikation beißt du dir daran die Zähne aus.

Dann freut sich mein Zahnarzt :D

Aber kannst gerne mit binärdaten experimentieren ;)

Konvertierfunktionen findet man im Internet obwohl du da bei der Kodierung aufpassen musst ob das int direkt ins byte oder in Low und high kodiert ist.

Soweit ich gesehn hab, hab ich nur Bytes.
Vielen, vielen Dank für's mitdenken und den richtigen Anstoss geben. Mal sehen, wie weit ich heute Abend damit komme - jetzt muss ich zwar doch Bytes zählen (das hatte ich gehofft, über den falschen Umweg mit dem String vermeiden zu können), aber mir is die Funktion wichtiger.

Ganz großes Dankschön!
Gruss
G.-U.M.

N'y pas n'y
tu car tu
mal tu mal

Antworten

Empfohlene Artikel