Einzelnen Beitrag anzeigen

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