![]() |
Unicode + BASE64?
Hallo.
Wieder mal eine meiner vielen Fragen zu Unicode bzw. WideStrings... Ich möchte einen WideString etwas chiffrieren, sodass dieser nicht direkt über einen HexEditor ausgelesen werden kann. Soll nur eine leichte Chiffrierung wie z.B. BASE64 sein. Jetzt hab ich hier eine schöne Unit für BASE64 gefunden: ![]() Gruß blackdrake |
Re: Unicode + BASE64?
Base64 würde ich dir auf jeden Fall nicht raten .. nimm eine einfache XOR Verschlüsselung oder die RCx Unit von Hagen. Wenn du Base64 verwendest kannst du das verschleiern auch gleich lassen :P
|
Re: Unicode + BASE64?
Hallo.
Danke für den Tipp. Ich schau mir das mal an. Gruß blackdrake |
Re: Unicode + BASE64?
Hallo.
Ich will nun DEC für die Verschlüsselung nutzen. Dort gibt es eine Funktion der Art Verschlüsselung(input: string): string. Ist es damit überhaupt möglich, einen WideString zu speichern? Kann es sein, dass bei der Umwandlung WideString -> String -> WideString alle Unicode-Zeichen (z.B. asiatische) verloren gehen? Ich kapiere es einfach nicht, wie ein WideString funktioniert. Eigentlich könnte der String bei der WideString -> String Umwandlung ja auch der String doppelt so lang werden, damit z.B. asiatische Zeichen nicht verloren gehen. Wie muss ich das jetzt machen? Gruß blackdrake |
Re: Unicode + BASE64?
Konvertiere einfach den String nach UTF8. Dürfte die einfachste Lösung sein. Oder du findest eine Funktion die mit Speicherbereichen (also Typlos) arbeitet und die Daten byteweise "anfaßt"
|
Re: Unicode + BASE64?
Du musst nur den Widestring in ein Byte-Array umwandeln und dann das Array verschlüsseln.
Beim Entschlüsseln lädst du das Byte-Array, entschlüsselst es und wandelst es dann in einen Widestring um. |
Re: Unicode + BASE64?
Hallo.
Bytearray? Wie soll ich das machen? Copy() funktioniert ja nur mit Strings. Somit kann ich keinen dynamischen "array of bytes" erstellen und ihn dann mit einer "for"-Schleife unter verwendung von "copy" füllen. Gruß blackdrake |
Re: Unicode + BASE64?
Weiss nich wie das mit Delphi geht. In C# könnt ichs dir sagen ;)
|
Re: Unicode + BASE64?
Na du deklarierst dir ein Array of Char (Char UND Byte = 0..255) verwendest SetLength(ByteArray, Length(UnicodeStr)) und kopierst mittels Copy(@ByteArray[0], @UnicodeStr[1], Length(UnicodeStr)) das ganze ins Array.
Dann kannst du der Funktion zum verschlüsseln einfach das ByteArray übergeben. Da dieses als Array of Char deklariert ist und somit nichts anderes als in String ist sollte Delphi das akzeptieren. Ansonsten einfach vorher nach String() typecasten. |
Re: Unicode + BASE64?
Mhh... so in etwa? Hier sagt er, es seien inkompatible Typen. :(
Delphi-Quellcode:
function WideStringToString_Lossyless(UnicodeStr: WideString): string;
var ByteArray: Array of Char; // Array of Byte begin SetLength(ByteArray, Length(UnicodeStr)); ByteArray := Copy(@ByteArray[0], @UnicodeStr[1], Length(UnicodeStr)); result := string(ByteArray); end; |
Re: Unicode + BASE64?
Welche Zeile genau?
|
Re: Unicode + BASE64?
Bei der Copy-Zeile. Ich glaube 2tes Argument.
|
Re: Unicode + BASE64?
Dann versuch mal nur @UnicodeStr oder UnicodeStr[0] .. keine Ahnung wie sich das genau verhält.
|
Re: Unicode + BASE64?
Zitat:
|
Re: Unicode + BASE64?
Wie soll ich denn sonst das Problem lösen? Ich muss den WideString ja irgendwie in einen String umwandeln, diesen dann ver- und entschlüsseln und diese Umwandlung danach wieder Rückgängig machen, ohne dass Informationen verloren gehen. Die Grundproblematik ist doch klar, oder? Das ich einen japanischen Text von WideString nicht nach String umwandeln kann, ohne dass dieser nur komische Zeichen enthält, ist mir klar.
Edit: Außerdem gilt #00 bei Strings bzw. #00#00 bei WideStrings ja nur speicherintern bzw bei Streams. Nach der Verschlüsselung hab ich ja nichts mehr dergleichen. Wenn ich einen String "test" habe, ist ja das #00 auch nur innerhalb des RAMs da und nicht im String selbst. |
Re: Unicode + BASE64?
Wieso musst du den Widestring in einen String umwandeln? Das geht nicht, da gehen dir Zeichen verloren. Du musst den Widestring in ein Byte-Array umwandeln und dieses dann verschlüsseln.
Das geht doch bestimmt über irgendwelche Pointer-tricks mit CopyMem(). Aber da kenn ich mich nicht wirklich aus. Ich gehe Pointern aus dem Weg ;) |
Re: Unicode + BASE64?
Das meine ich ja, mit Byte-Array zwischenstufe. Der String soll aufgebläht sein, sodass eben keine Informationen verloren gehen. Ist unter Umständen das vorher genannte UTF-8 das, was ich suche?
Wie gesagt, die strings sollen nur als Übergang dienen, weil die Verschlüsselungsroutine nur strings annimmt. Sie sollen keinen Sinn ergeben. CopyMem() gibt's als Funktion nicht. Und Copy() dient trotz seiner Bezeichnung nur zum Abschneiden von Strings. |
Re: Unicode + BASE64?
Ist CopyMem nicht so n toller Win32-API-Call?
Dass die Verschlüsselungsroutine nur Strings annimmt, is schon ein bisschen doof, wenn man Unicode verarbeiten will. Kannste die nicht auf ein byte-Array umschreiben? Ein WideChar ist ja 16 Bit, ein normaler Char nur 8 Bit. Wenn du nun von deinem Widechar jeweils die ersten 8 Bit (Hi) in den ersten Char und die letzten 8 Bit (Lo) in den nächsten char kopierst, dann hast du einen doppelt so langen String, aber ohne Verlust von Informationen. Diesen kannst du dann verschlüsseln. Aber ich weiss nicht, ob eventuelle #0 im String Delphi durcheinanderbringen (aber ich denke, Delphi verwaltet die Strings anders als C mit den null-terminierten Strings)... |
Re: Unicode + BASE64?
Danke für den Hinweis.
Delphi hat keine Probleme mit Strings und #0. Man hat lediglich Probleme wenn man einen solchen String ausgeben möchte. Er wirkt wie abgeschnitten, was er aber nicht ist. Folgendes Funktioniert nun:
Delphi-Quellcode:
Jetzt bin ich nur noch am rumprobieren mit der Reverse-Funktion:
function WideStringToString_Lossyless(UnicodeStr: WideString): string;
var ByteArray: Array of Char; begin SetLength(ByteArray, Length(UnicodeStr)); CopyMemory(@ByteArray[0], @UnicodeStr[1], Length(UnicodeStr)); result := string(ByteArray); end;
Delphi-Quellcode:
Diese funktioniert aber nicht ganz...
function DoubleStringToWideString(DoubleString: WideString): widestring;
var ByteArray: Array of WideChar; begin SetLength(ByteArray, Length(DoubleString) div 2); CopyMemory(@DoubleString[1], @ByteArray[0], Length(ByteArray)); result := widestring(ByteArray); end; procedure TForm1.Button1Click(Sender: TObject); begin // Sollte exakt ANSI "test" sein showmessage(DoubleStringToWideString(WideStringToString_Lossyless('test'))); end; |
Re: Unicode + BASE64?
Wie schon gesagt: Entweder du suchst dir eine Funktion die mit einfachen Pointer + Längenangabe arbeitet oder du wandelst den String nach UTF8 um und hast das Ergebnis dan in einen String.
Deine Hacker-Funktionen werden scheitern wenn dein bisher ausgesuchte Base64-Methode geziehlt ein #$00 als Stop-Byte annimmt. Schon mal überlegt ob die Zeile
Delphi-Quellcode:
richtig ist wenn eine WideString-Character 2 Bytes einnimmt :gruebel:
SetLength(ByteArray, Length(UnicodeStr));
|
Re: Unicode + BASE64?
Als Hintergrundinformation: Ein String ist ein Array of Char = Array of Byte. Insofern haben Strings überhaupt keine Probleme mit #0. Der Datentyp welcher damit Probleme hat, weil er ihn als Trennzeichen ansieht ist PChar, bzw PAnsiChar.
|
Re: Unicode + BASE64?
Zitat:
![]() Und da wir nicht wissen ob die zu verwendenten Base64-Funktion intern mit PChar's gearbeitet wird bzw. irgendwelche WinAPI-Funktionen aufgerufen werden wäre es mit Vorsicht zu genießen eine Widestring per Speicher-Copy in einen String zu "konvertieren". |
Re: Unicode + BASE64?
Mensch, ist das ein Ärger mit Unicode + Delphi :? Die Fragestellung ist so simpel und die Lösung komplex.
Hilft folgendes zur Klärung der "Problem mit #0"-Frage?
Delphi-Quellcode:
Ich kenne mich mit Pointern nicht so wirklich aus...
type
Binary = String; // LongString with Binary Contens function TDECCipher.EncodeBinary(const Source: Binary; Format: TDECFormatClass): Binary; begin SetLength(Result, Length(Source)); Encode(Source[1], Result[1], Length(Source)); Result := ValidFormat(Format).Encode(Result); end; procedure TDECCipher.Encode(const Source; var Dest; DataSize: Integer); // ... procedure EncodeECBx(S,D: PByteArray; Size: Integer); // ... begin //... EncodeECBx(@Source, @Dest, DataSize); //... end; |
Re: Unicode + BASE64?
Aus dem Bauch heraus:
Delphi-Quellcode:
function EncodeWideString(const Source: WideString; Format: TDECFormatClass): String;
var iSize: Integer; begin iSize := Length(Source)*SizeOf(WideChar); SetLength(Result, iSize); Encode(Source[1], Result[1], iSize); Result := ValidFormat(Format).Encode(Result); end; |
Re: Unicode + BASE64?
Ich probiere jetzt schon seit 3:30h alle verschiedenen Varianten rum und nichts funktioniert :( Mir fällt bald mein Abendessen aus dem Gesicht.
UTF8 hab ich auch schon probiert, auch negativ Ich habe für die Verschlüsselungsfunktion auch ein Gegenstück entwickelt, doch dann herausgefunden, dass der Entschlüsselungskern nur Strings nehmen will. Desweiteren habe ich herausgefunden, dass meine Funktion nicht geht:
Delphi-Quellcode:
Dieser Code soll einfach nur uni.txt (42 Byte) mit Inhalt
function WideStringToDoubleLongString(UnicodeStr: WideString): string;
var ByteArray: Array of Char; PWC: PWideChar; begin SetLength(ByteArray, Length(UnicodeStr) * sizeof(WideChar)); PWC := PWideChar(UnicodeStr); CopyMemory(@ByteArray[0], @PWC, Length(UnicodeStr) * sizeof(WideChar)); result := string(ByteArray); end; 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; procedure TForm1.Button1Click(Sender: TObject); var test: TFileStream; ws: widestring; s: string; begin test := TFileStream.Create('c:\uni.txt', fmOpenRead or fmShareDenyNone); ws := ReadNullTerminatedWideString(test); s := WideStringToDoubleLongString(ws); test.free; deletefile('c:\uni2.txt'); test := TFileStream.Create('c:\uni2.txt', fmCreate); test.writebuffer(s, length(s)); test.free; end; testこれはちょうどテストであtest[null][null] nach uni2.txt "kopieren". Erst wenn dies Funktioniert, kann ich weiter machen. Die Größe der Ausgabedatei uni2.txt stimmt. Es sind 40 Byte (keine Null-Terminierung, deswegen nicht 42). Aber der Inhalt stimmt nicht: ꡈí渊Cê拯B揭Bê椂C Weiß denn niemand, wie ich die Inhalte eines WideStrings vorrübergehend in einen String lagern kann? Gruß blackdrake |
Re: Unicode + BASE64?
Delphi-Quellcode:
Ist ja auch klar. Du versuchst jedliche "Compiler-Magic" bezüglich Referenzzählung bei Strings mit der Holzhammermethode (Harte Casts) zu erschlagen.
Desweiteren habe ich herausgefunden, dass meine Funktion nicht geht:
Schon mal überlegt das deine lokale Variable
Delphi-Quellcode:
automatisch beim verlassen der Funktion WideStringToDoubleLongString Speichertechnisch freigegeben wird und du dann als result-Parameter einen Nirvana-Pointer hast?
ByteArray: Array of Char;
Und fürs einlesen von Unicode-Textdateien (Neue Frage -> Neuer Thread) gibt es das ElPack, die TNTWare-Controls oder entsprechende Funktionen in der CodeLib (welche das ist lass ich dir jetzt mal selbst suchen). Zitat:
Hast du überhaupt meinen letzten Post gelesen wie du die DEC-Methode mit Widestrings aufrufen könntest? |
Re: Unicode + BASE64?
Zitat:
Wieso funktioniert denn UTF8 nicht? ![]() ![]() UTF8 wäre auch bei wenigen speziellen Zeichen (bspw. dt. Sprache) speichereffizienter als andere Unicode-Kodierungen. |
Re: Unicode + BASE64?
Hallo.
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. Zitat:
Das mit dem Einlesen der Unicode-Datei dient nur als Beispiel, damit ich einen japanischen Vorlagetext habe, mit dem ich testen kann. Ich brauche keine VCL, um einen WideString von einem Stream einzulesen. Zitat:
Tut mir leid, dass ich mich hier so wenig auskenne. Aber es muss doch möglich sein, dass man einen WideString verschlüsselt. Man kann doch nicht die ganze DEC umschreiben, weil die Kernfunktionen nur strings annehmen. Versteht ihr die Grundproblematik nicht? WideString mit 10 Zeichen á 2 Bytes -> Char-Array -> String mit 20 Zeichen -> Verschlüsselter Text (keine Probleme mit #0!!!) Verschlüsselter Text (keine Probleme mit #0!!!) -> String mit 20 Zeichen -> Char-Array -> WideString mit 10 Zeichen á 2 Bytes Was soll daran unmöglich sein, 20 Bytes Widestring in 20 Bytes String umzuwandeln? Ob ein #0 in der Mitte vorkommt, ist dem DEC, das binäre Daten akzeptiert, egal. Ich kann als Hobbyprogrammierer nur die Dinge, die ich mir selbst angeeignet habe. Also wäre ich dankbar, wenn ich Code anstatt von großen Sprüchen oder Fachbegriffen bekommen würde. Die helfen mir nichts. Es kann nicht sein, dass man 20 Bytes nicht in 20 Bytes umwandeln kann!!! Im Arbeitsspeicher sehen diese 20 Bytes alle gleich aus, egal ob sie als WideString oder als String interpretiert werden! Gruß blackdrake |
Re: Unicode + BASE64?
Zitat:
ByteArray wird genommen und als String umgewandelt. Und ein String ist kein Pointer. Folglich zeigt result nicht ins leere. Oder nicht? Bitte zeig mir lieber, wie man mit Codebeispielen es besser macht, anstatt an meinem Code rumzumeckern. Ich bin kein Fachinformatiker, aber ich sehe hier nicht, dass result ein Pointer ist. Result ist außerdem vom Typ "string". Folglich kein Pointer, der ins nichts zeigen kann. Gruß blackdrake |
Re: Unicode + BASE64?
Am einfachsten wäre doch:
Delphi-Quellcode:
Wobei ICH auch glaube, dass String(ByteArray) funktioniert. Warum probierst dus nicht einfach aus?
var
Str: String; ByteArray: Array of Char; // .. begin // .. SetLength(Str, Length(ByteArray) -1); Copy(@Str[1], @ByteArray[0], Length(ByteArray)); end; |
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 21:28 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