![]() |
Re: Unicode + BASE64?
Hallo.
Wo ist da der Eingabe-Unicode-String? CopyMemory verwende ich ja bereits. Im Beitrag #25 ( ![]() 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:
Wobei ich auch schreiben könnte (was aber Probleme bei UnicodeStr = '' machen kann)
PWC := PWideChar(UnicodeStr);
CopyMemory(@ByteArray[0], @PWC, Length(UnicodeStr) * sizeof(WideChar));
Delphi-Quellcode:
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.
CopyMemory(@ByteArray[0], @UnicodeStr[1], Length(UnicodeStr) * sizeof(WideChar));
Gruß blackdrake |
Re: Unicode + BASE64?
Zitat:
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. |
Re: Unicode + BASE64?
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.
|
Re: Unicode + BASE64?
Hinzu:
Delphi-Quellcode:
Rückzu:
var
as: AnsiString; // Ausgabe ws: WideString; // Eingabe begin SetLength(as, Length(ws)); CopyMemory(@as[1], @ws[1], Length(as)); end;
Delphi-Quellcode:
Und nein, das macht keine Probleme bei einem leeren WideString, weil Delphi die "automagisch" nullterminiert, womit immer eine Null da sein sollte.
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; |
Re: Unicode + BASE64?
Liste der Anhänge anzeigen (Anzahl: 1)
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:
Die Datei c:\uni.txt muss den Text
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; testこれはちょうどテストであtes[NULL][NULL] enthalten. Außerdem habe ich noch sowas hier probiert. Ebenfalls alles ohne Erfolg!
Delphi-Quellcode:
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!! :( :(
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; EDIT Ich demonstriere nochmal, dass meine Lese- / Schreibfunktionen nicht schuld sind. Es wird ein WideString korrekt eingelesen und anschließend wieder geschrieben.
Delphi-Quellcode:
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.
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; Gruß blackdrake |
Re: Unicode + BASE64?
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.
|
Re: Unicode + BASE64?
Wenn ich noch den Donwload zu der Unit für TDECCipher hätte, hätte ich schnell mal ein Lösung gezimmert.
|
Re: Unicode + BASE64?
Hier kannst du DEC herunterladen:
![]() |
Re: Unicode + BASE64?
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:
Ich hoffe dass diese Funktionen all denen viel Arbeit abnehmen, die das selbe Problem (WideString mit einer String-Funktion zu bearbeiten) haben.
// 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 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:
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.
// 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; PS: Wäre doch was für die CodeLib, oder? Gruß blackdrake |
Re: Unicode + BASE64?
Kleine Zwischenfrage: Hagens DEC besitzt doch auch eine EncodeBinary Funktion .. kann man der nicht den WideString ohne Weiteres übergeben?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:38 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-2025 by Thomas Breitkreuz