AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Unicode + BASE64?

Ein Thema von blackdrake · begonnen am 20. Aug 2007 · letzter Beitrag vom 27. Aug 2007
Antwort Antwort
Seite 4 von 6   « Erste     234 56      
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#31

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 00:49
Hallo.

Wo ist da der Eingabe-Unicode-String? CopyMemory verwende ich ja bereits. Im Beitrag #25 ( http://www.delphipraxis.net/internal...=767710#767710 ) habe ich ja das ganze Beispiel beigelegt, das man direkt Testen kann.

Ich lese eine Unicodedatei ein, wandle den x Byte WideString in einen x Byte String und speichere anschließend den String. Speichern und Laden funktioniert, aber die Dateien sind unterschiedlich!

Die entscheidende Zeile ist ja:

Delphi-Quellcode:
PWC := PWideChar(UnicodeStr);
CopyMemory(@ByteArray[0], @PWC, Length(UnicodeStr) * sizeof(WideChar));
Wobei ich auch schreiben könnte (was aber Probleme bei UnicodeStr = '' machen kann)

CopyMemory(@ByteArray[0], @UnicodeStr[1], Length(UnicodeStr) * sizeof(WideChar)); Ich sehe in dieser Funktion: 20 Bytes von Position @UnicodeStr zu Position @ByteArray kopieren. Das muss doch funktionieren. Ich verstehe gar nicht, wieso etwas völlig verschiedenes rauskommt. Er muss den Inhalt vom WideString in den String schreiben. Auf die #0 in der Mitte kommt es hier wie gesagt gar nicht an. Das Problem ist hier was anderes.

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#32

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 00:55
Zitat von blackdrake:
UTF8Decode() und UTF8Encode() haben nur Schrott ausgegeben.

EDIT: Außerdem sind diese Funktionen von der Codepage abhängig. Ich will ja den String nicht verwenden, um ihn anzeigen zu lassen, sondern ihn nur als Container verwenden, der die Inhalte des WideStrings besitzt. Er ist doppelt so groß und kann #0 enthalten, was aber DEC egal ist.
Überhaupt mal den Links gefolgt? Die Codepage kann man bei den verlinkten Funktionen nämlich auch sehr wohl angeben.

Und nein, wenn du asiatische Zeichen hast, sind es eben keine Nullen im "HiByte", weil dann nämlich der Platz gebraucht wird um eine eindeutige Zuordnung zu gewährleisten. Das ist ja das ganze Dilemma.
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#33

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 01:01
Hallo. Mit den Funktionen hatte ich mich schon vergebens beschäftigt. Ich will ja hier codepageunabhängig konvertieren. Dass bei Unicodezeichen der Hi-Byte besetzt ist (außer es handelt sich um die ANSI-Zeichen, die im Unicode mit enthalten sind), ist mir klar. Ich will ja Lo- UND Hi-Byte in einen String packen. Dieser soll keinen Sinn ergeben, sondern nur dazu dienen, um korrekt verschlüsselt zu werden. Der String ist aufgebläht und doppelt so groß, wie ich schon beschrieben habe. Folglich ist die Codepage völlig egal. Es soll lediglich der Speicherinhalt des WideStrings in den String kopiert werden, wodurch dieser doppelt so groß wird. Ich erwähne das mit dem #0, weil hier einige behaupten, es würde dadurch nur zu Problemen kommen, was aber in meinem Fall eben nicht so ist, da DEC als Eingabe Strings mit enthaltenem #0 akzeptiert.
Daniel Marschall
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#34

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 01:32
Hinzu:
Delphi-Quellcode:
var
as: AnsiString; // Ausgabe
ws: WideString; // Eingabe
begin
  SetLength(as, Length(ws));
  CopyMemory(@as[1], @ws[1], Length(as));
end;
Rückzu:
Delphi-Quellcode:
var
as: AnsiString; // Eingabe
ws: WideString; // Ausgabe
begin
  SetLength(ws, Length(as div sizeof(WideChar)));
  CopyMemory(@ws[1], @as[1], Length(ws) * sizeof(WideChar));
end;
Und nein, das macht keine Probleme bei einem leeren WideString, weil Delphi die "automagisch" nullterminiert, womit immer eine Null da sein sollte.
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#35

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 01:42
Hallo.

Danke für die Codeteile. Leider funktioniert es auch nicht ganz. Ich habe auch ergänzend sizeof(WideChar) dazugehängt.

"testこれはちょうどテストであtes" wird bei deinem Beispiel zu "ₘî淪C๰ê" (nur halb so lang weil *2 vergessen, was aber jetzt auch erstmal egal ist).

Probier es selbst aus:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  function ReadNullTerminatedWideString(const Stream: TStream): WideString;
  var
    S: WideString;
    WC: WideChar;
  begin
    S := '';
    repeat
      Stream.ReadBuffer(WC, 2);
      if (WC <> #0) then
        S := S + WC;
    until WC = #0;
    Result := S;
  end;

var
  test: TFileStream;
  ws: widestring;
  ans: AnsiString;
begin
  test := TFileStream.Create('c:\uni.txt', fmOpenRead or fmShareDenyNone);
  ws := ReadNullTerminatedWideString(test);

  SetLength(ans, Length(ws));
  CopyMemory(@ans[1], @ws[1], Length(ans));

  test.free;

  deletefile('c:\uni2.txt');
  test := TFileStream.Create('c:\uni2.txt', fmCreate);
  test.writebuffer(ans, length(ans));
  test.free;
end;
Die Datei c:\uni.txt muss den Text

testこれはちょうどテストであtes[NULL][NULL]

enthalten.

Außerdem habe ich noch sowas hier probiert. Ebenfalls alles ohne Erfolg!

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  function ReadNullTerminatedWideString(const Stream: TStream): WideString;
  var
    S: WideString;
    WC: WideChar;
  begin
    S := '';
    repeat
      Stream.ReadBuffer(WC, 2);
      if (WC <> #0) then
        S := S + WC;
    until WC = #0;
    Result := S;
  end;

var
  test: TFileStream;
  ws: widestring;
  s: string;
  PWC: PWideChar;
  data: array of pchar; // string, array of char und pchar gingen auch nicht
begin
  test := TFileStream.Create('c:\uni.txt', fmOpenRead or fmShareDenyNone);
  ws := ReadNullTerminatedWideString(test);

  PWC := PWideChar(ws);

  //Data := GetMemory(Length(ws) * sizeof(WideChar));

  SetLength(Data, Length(ws) * sizeof(WideChar));

  // Hab schon mit und ohne @ sowie mit und ohne [0] ausprobiert, ging alles nicht
  CopyMemory(@Data[0], @PWC, Length(ws) * sizeof(WideChar));

  s := string(Data);

  test.free;

  deletefile('c:\uni2.txt');
  test := TFileStream.Create('c:\uni2.txt', fmCreate);
  test.writebuffer(s, length(s));
  test.free;
end;
Ob es jetzt sinnvoll ist oder nicht, was ich hier mache. Ist eigentlich egal. Aber irgendwie muss es doch funktionieren, dass man per CopyMemory einen Variableninhalt von x nach y kopiert. Hier ist irgendwo der Wurm drin!!

EDIT

Ich demonstriere nochmal, dass meine Lese- / Schreibfunktionen nicht schuld sind. Es wird ein WideString korrekt eingelesen und anschließend wieder geschrieben.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  function ReadNullTerminatedWideString(const Stream: TStream): WideString;
  var
    S: WideString;
    WC: WideChar;
  begin
    S := '';
    repeat
      Stream.ReadBuffer(WC, 2);
      if (WC <> #0) then
        S := S + WC;
    until WC = #0;
    Result := S;
  end;

var
  test: TFileStream;
  ws: widestring;
  pwc: pwidechar;
begin
  test := TFileStream.Create('c:\uni.txt', fmOpenRead or fmShareDenyNone);
  ws := ReadNullTerminatedWideString(test);
  test.free;

  deletefile('c:\uni2.txt');
  test := TFileStream.Create('c:\uni2.txt', fmCreate);
  pwc := PWideChar(ws);
  test.write(pwc^, length(ws) * sizeof(widechar));
  test.WriteBuffer(#00#00, 2);
  test.free;
end;
uni.txt und uni2.txt sind danach absolut identisch. Es liegt wie gesagt bei der Umwandlung des WideStrings in einen doppelt großen Ansi-String.

Gruß
blackdrake
Angehängte Dateien
Dateityp: txt uni_114.txt (42 Bytes, 3x aufgerufen)
Daniel Marschall
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#36

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 05:21
Kann es leider nicht ausprobieren, da ich kein Delphi installiert habe. Da werde ich mich wohl aus der Diskussion ausklinken müssen, wenn ich nichts sinnvolles beitragen kann.
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.203 Beiträge
 
Delphi 10.4 Sydney
 
#37

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 14:51
Wenn ich noch den Donwload zu der Unit für TDECCipher hätte, hätte ich schnell mal ein Lösung gezimmert.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#38

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 14:52
Hier kannst du DEC herunterladen: http://www.michael-puff.de/Developer...agen_Reddmann/
Daniel Marschall
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#39

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 18:27
Hallo.

Nach 2 Tagen rumprobieren und verzweifeln, bin ich doch noch auf einen grünen Zweig gekommen. Wie ich bereits zuvor behauptet habe und was hier quasi jeder bestritten hat, funktioniert es doch, einen WideString in einen aufgeblähten AnsiString zu lagern und umgekehrt.

Der Code sieht so aus:

Delphi-Quellcode:
// WideString-Inhalte in einen AnsiString schreiben (dieser ist 2-Mal so groß)

function WideStringToDoubleLongAnsiString(ws: WideString): AnsiString;
var
  i: integer;
  wc: widechar;
begin
  result := '';
  for i := 1 to length(ws) do
  begin
    copymemory(@wc, @ws[i], sizeof(wc));
    result := result + chr(lo(ord(wc))) + chr(hi(ord(wc)));
  end;
end;

function DoubleLongAnsiStringToWideString(dls: AnsiString): WideString;

  // [url]http://www.delphipraxis.net/post27809.html[/url]
  function HexToInt(HexNum: string): LongInt;
  begin
    Result:=StrToInt('$' + HexNum);
  end;

  function BuildWideChar(char2, char1: char): WideChar;
  begin
    result := widechar(hextoint(inttohex(ord(char1), 2)+inttohex(ord(char2), 2)));
  end;

var
  i: integer;
  c: array [0..1] of char;
begin
  i := -2;
  result := '';
  repeat
    i := i + 2;
    if i >= length(dls) then break;
    copymemory(@c[0], @dls[i+1], sizeof(c));
    result := result + BuildWideChar(c[0], c[1]);
  until false;
end;
Ich hoffe dass diese Funktionen all denen viel Arbeit abnehmen, die das selbe Problem (WideString mit einer String-Funktion zu bearbeiten) haben.

Ich kann hier perfekt einen WideString in einen doppelt so großen AnsiString packen, diesen mit DEC (das nur Strings annimmt) verschlüsseln und das ganze dann wieder rückwärts laufen lassen. Somit habe ich einen WideString ver- und entschlüsselt.

Und angenommen, es würde Probleme mit #0 oder was-weiß-ich-was geben, dann ersetze ich einfach chr() mit inttohex() und hänge somit die Hexadezimalen Werte der Wide-Char-Halbierungen hinereinander (FFFE1F...). Dann wäre der AnsiString 4 Mal so groß und würde keine binären Zeichen mehr enthalten, aber dann gibt es absolut keine Probleme mehr! Hier ist der Beispielcode:

Delphi-Quellcode:
// Hexadezimale WideString-Inhalte in einen AnsiString schreiben (dieser ist 4-Mal so groß)

function WideStringToHexAnsiString(ws: WideString): AnsiString;
var
  i: integer;
  wc: widechar;
begin
  result := '';
  for i := 1 to length(ws) do
  begin
    copymemory(@wc, @ws[i], sizeof(wc));
    result := result + inttohex(lo(ord(wc)), 2) + inttohex(hi(ord(wc)), 2);
  end;
end;

function HexAnsiStringToWideString(dls: AnsiString): WideString;

  // [url]http://www.delphipraxis.net/post27809.html[/url]
  function HexToInt(HexNum: string): LongInt;
  begin
    Result:=StrToInt('$' + HexNum);
  end;

  function BuildWideChar(char2, char1: char): WideChar;
  begin
    result := widechar(hextoint(inttohex(ord(char1), 2)+inttohex(ord(char2), 2)));
  end;

var
  i: integer;
  c: array [0..3] of char;
begin
  i := -4;
  result := '';
  repeat
    i := i + 4;
    if i >= length(dls) then break;
    copymemory(@c[0], @dls[i+1], sizeof(c));
    result := result + BuildWideChar(Chr(HexToInt(c[0]+c[1])), Chr(HexToInt(c[2]+c[3])));
  until false;
end;
Ich danke denen, die sich mit dem Problem beschäftigt haben und mir Codeteile gegeben haben anstelle von großen Sprüchen. Auch bedanke ich mich bei den C-Leuten, die mich auf die CopyMemory Idee gebracht haben.

PS: Wäre doch was für die CodeLib, oder?

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#40

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 18:46
Kleine Zwischenfrage: Hagens DEC besitzt doch auch eine EncodeBinary Funktion .. kann man der nicht den WideString ohne Weiteres übergeben?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 6   « Erste     234 56      


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 00:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz