AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung String zu Byte-Array konvertieren und umgekehrt
Thema durchsuchen
Ansicht
Themen-Optionen

String zu Byte-Array konvertieren und umgekehrt

Ein Thema von knaeuel · begonnen am 15. Mär 2018 · letzter Beitrag vom 15. Mär 2018
Antwort Antwort
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#1

String zu Byte-Array konvertieren und umgekehrt

  Alt 15. Mär 2018, 12:10
Hallo zusammen, ich habe folgendes Problem:

Ich muss für einen an sich recht simplen späteren Vorgang Strings zu Byte-Arrays konvertieren und umgekehrt. Die Umwandlung muss auf den 3 Plattformen Windows, iOS und Android dieselben Ergebnisse liefern - und genau da liegt der Knackpunkt.

Auf Windows funktioniert das problemlos, ich konvertiere Text zu Bytes und wieder zurück und habe wieder den Ausgangstext vorliegen.
Auf Android und iOS wandle ich den Text in Bytes um -> bis hierhin stimmen die Daten mit dem Windows-System überein - aber die Rückumwandlung liefert einen völlig anderen String, übrigens auf Android und iOS identisch.

konkretes Beispiel:
String:
"12345678 einszwo"

Wandlung zu Byte-Array liefert:
$31 $32 $33 $34 $35 $36 $37 $38 $20 $65 $69 $6E $73 $7A $77 $6F

Rückumwandlung auf iOS und Android liefert:
aus Delphi-Debugger kopiert: "#003#023'#3CScs'#202#006'V'#226'ç7§v'"
optische Abtipp-Kopie: " #3CScs_ V_ç7§v"
(die beiden _ sind eigentlich viereckige Kästchen mit Kreuzchen drin)

Folgende functions setze ich zur Wandlung ein (Aufruf folgt weiter unten):
Delphi-Quellcode:
//wandelt ein byte-array in hex-text um, 2 zeichen je byte
function TForm1.bytearray2HexString(input:array of byte):string;
var einhexbyte:string;
    i:integer;
begin
  result:='';
  for i:=0 to length(input)-1 do
  begin
    einhexbyte:=Format('%x',[input[i]]);
    if length(einhexbyte)=1 then
      einhexbyte:='0'+einhexbyte;
    result:=result+einhexbyte;
  end;
end;

function TForm1.TxtString2HexString(s:string):string;
var p,i:integer;
    hilfsar:array of byte;
begin
  //soll Text in die jeweiligen Hex-Zeichencodes übersetzen
  //und aus den Zeichencodes einen neuen String als result basteln
  //Zeichenweise durch den Quellstring laufen
  //und dabei zunächst als Byte-Array speichern
  setlength(hilfsar,0);
{$IFDEF MSWINDOWS}
  for i:=1 to length(s) do
{$ELSE} //auf iOS und Android sind die Strings 0-basiert...
  for i:=0 to length(s)-1 do
{$ENDIF}
  begin
    //in byte-array schreiben
    p:=length(hilfsar);
    setlength(hilfsar,p+1);
    hilfsar[p]:=ord(s[i]);
  end;
  //anschließend bytearray2HexString aufrufen - fertig
  result:=bytearray2HexString(hilfsar);
end;

function TForm1.HexStringToByteArray(input:string):System.TArray<System.Byte>;
var i,p:integer;
begin
  //immer 2 Zeichen nehmen und zum Hexwert machen
  setlength(result,0);
{$IFDEF MSWINDOWS}
  for i:=1 to length(input) do
{$ELSE} //auf iOS und Android sind die Strings 0-basiert...
  for i:=0 to length(input)-1 do
{$ENDIF}
  begin
    if i mod 2 = 0 then
    begin
      p:=length(result);
      setlength(result,p+1);
      result[p]:=TwoHexCharsToInt(input[i-1],input[i]);
    end;
  end;
end;

//wandelt eine als String gespeicherte Hexadezimalzahl in eine Dezimalzahl
//und speichert sie im Result
function TForm1.TwoHexCharsToInt(charhigh,charlow:char):integer;
begin
  result:=0;
  case charhigh of
  '0': result:=16*0;
  '1': result:=16*1;
  '2': result:=16*2;
  '3': result:=16*3;
  '4': result:=16*4;
  '5': result:=16*5;
  '6': result:=16*6;
  '7': result:=16*7;
  '8': result:=16*8;
  '9': result:=16*9;
  'A','a': result:=16*10;
  'B','b': result:=16*11;
  'C','c': result:=16*12;
  'D','d': result:=16*13;
  'E','e': result:=16*14;
  'F','f': result:=16*15;
  end;
  case charlow of
  '0': result:=result+0;
  '1': result:=result+1;
  '2': result:=result+2;
  '3': result:=result+3;
  '4': result:=result+4;
  '5': result:=result+5;
  '6': result:=result+6;
  '7': result:=result+7;
  '8': result:=result+8;
  '9': result:=result+9;
  'A','a': result:=result+10;
  'B','b': result:=result+11;
  'C','c': result:=result+12;
  'D','d': result:=result+13;
  'E','e': result:=result+14;
  'F','f': result:=result+15;
  end;
end;

function TForm1.TranslateToText(input:array of byte):string;
var i:integer;
begin
  result:='';
  for i:=0 to length(input)-1 do
    result:=result+chr(input[i]);
end;
Der Aufruf zur Wandlung vom Text zum Bytearray sieht so aus:
(das Byte-Array existiert nur kurz und wird dann in einen String umgeschrieben: z.B. aus 2 Bytes $0B $A1 würde der String "0BA1")
Delphi-Quellcode:
var ursprungstext,hexstring:string;

//Wandlung: String -> Hex-String (aus Byte-Array)
ursprungstext:='12345678 einszwo';
hexstring:=TxtString2HexString(ursprungstext);

//Wandlung: Byte-Array (aus Hex-String) -> String
ursprungstext:=TranslateToText(HexStringToByteArray(hexstring));
Ich verstehe nicht, wie die Übersetzung vorwärts und rückwärts unterschiedliche Ergebnisse liefern kann? Wo liegt mein (Denk-)Fehler? Ich bin für jede Hilfe dankbar!

Wie bekomme ich Android und iOS dazu, dieselben Ergebnisse zu liefern, wie Windows?
Wolfgang
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#2

AW: String zu Byte-Array konvertieren und umgekehrt

  Alt 15. Mär 2018, 12:18
Erstmal, in Android/iOS fängt String bei 0 an.

http://docwiki.embarcadero.com/RADSt...trings_(Delphi)
http://docwiki.embarcadero.com/RADSt...-Typen_(Delphi)

Low(string) = 0 auf Android/iOS
Low(string) = 1 auf Windows

[edit]
Upss, schon beachtet, aber Low() statt IFDFF ist bestimmt schöner.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.919 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: String zu Byte-Array konvertieren und umgekehrt

  Alt 15. Mär 2018, 12:23
TEncoding.GetBytes() ?
Funktioniert plattform-übergreifend und ist seit einigen Delphi-Versionen mit dabei.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#4

AW: String zu Byte-Array konvertieren und umgekehrt

  Alt 15. Mär 2018, 12:29
Zitat:
Delphi-Quellcode:
{$IFDEF MSWINDOWS}
  for i:=1 to length(input) do
{$ELSE} //auf iOS und Android sind die Strings 0-basiert...
  for i:=0 to length(input)-1 do
{$ENDIF}
if i mod 2 = 0 then
=0 ... je nach String-Typ ist der Vergleich auf den Systemen unterschiedlich.
Jeweils das erste Zeichen oder das zweite Zeichen.


Vorschlag:
Mit TEncoding.Default den String in ein TBytes (ANSI) und das dann z.B. via BinToHex nach HEX.
Andersrum HexToBin und dann via TEncoding.Default von TBytes nach String.


Zitat:
Delphi-Quellcode:
if length(einhexbyte)=1 then
      einhexbyte:='0'+einhexbyte;
Format kennt auch führende Nullen, siehe OH.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: String zu Byte-Array konvertieren und umgekehrt

  Alt 15. Mär 2018, 14:55
Danke schon mal für die Antworten!

Ich probiere mich mal mit "TEncoding.GetBytes()"
Wolfgang
  Mit Zitat antworten Zitat
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: String zu Byte-Array konvertieren und umgekehrt

  Alt 15. Mär 2018, 15:46
ich hab noch einen Fehler gefunden, der das Problem löst...

dieses Code-Fragment:
Delphi-Quellcode:
{$IFDEF MSWINDOWS}
  for i:=1 to length(input) do
{$ELSE} //auf iOS und Android sind die Strings 0-basiert...
  for i:=0 to length(input)-1 do
{$ENDIF}
  begin
    if i mod 2 = 0 then
sollte so aussehen:
Delphi-Quellcode:
{$IFDEF MSWINDOWS}
  for i:=1 to length(input) do
  begin
    if i mod 2 = 0 then
{$ELSE} //auf iOS und Android sind die Strings 0-basiert...
  for i:=0 to length(input)-1 do
  begin
    if (i+1) mod 2 = 0 then
{$ENDIF}
Wolfgang
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#7

AW: String zu Byte-Array konvertieren und umgekehrt

  Alt 15. Mär 2018, 17:31
Hatte ich zwar schon genannt und wenn man das dann auch noch alles umsetzt, dann kommt in etwa sowas bei raus
Delphi-Quellcode:
for i := Low(string) to High(input) do
begin
  if i mod 2 <> Low(string) then
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz