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 5 von 6   « Erste     345 6      
Olli
(Gast)

n/a Beiträge
 
#41

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 17:47
Ähem, vielleicht guckst du doch nochmal. Das Problem ist, beim String die Compiler-Magic auszutricksen. Ich habe hier niemanden gesehen, der bestritten hat, daß man den AnsiString auch als Puffer benutzen kann. Schon bevor ich meine beiden Code-Schnipsel gepostet habe, haben andere sehr ähnlichen Code gepostet. Wenn es nicht geht(/ging) liegt das an fehlenden Typecasts. Aber man müßte doch dann von dir erwarten können, daß du in der Lage bist den Code so zu variieren, daß es klappt

Zitat von blackdrake:
PS: Wäre doch was für die CodeLib, oder?
Lieber nicht. Es sei denn als Schaustück für eine ineffiziente Methode das besagte erreichen zu wollen


Zacherl's Idee klingt für mich übrigens sehr gut.

Length(ws) * sizeof(WideChar) sollte es dann ja tun ...
  Mit Zitat antworten Zitat
blackdrake

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

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 17:56
Hallo.

Zitat von Zacherl:
Kleine Zwischenfrage: Hagens DEC besitzt doch auch eine EncodeBinary Funktion .. kann man der nicht den WideString ohne Weiteres übergeben?
Binary ist nur ein anderes Wort für String. Als Kommentar ist hinterlegt, dass hier binäre Daten rein dürfen.

EncodeBinary nimmt einen binary an und übergibt dann an die Kernfunktionen (AES, BlowFish, ... -> DoEncode), die auch nur "binary" (=string) annehmen.

Bei DecodeBinary ist das genau so. Die Kernfunktionen (DoDecode) geben einen binary zurück.

Man muss also meine Funktionen verwenden, um einen WideString in einen String umzuwandeln, damit dieser verschlüsselt werden kann. Bei der Entschlüsselung würde man dann diesen Schritt wieder rückgängig machen. Und wenn es Probleme gibt, verwendet man einen Hex-String, der nicht-binär ist.

Zitat von Olli:
Ähem, vielleicht guckst du doch nochmal. Das Problem ist, beim String die Compiler-Magic auszutricksen.
Ich weiß leider nicht, was du meinst.

Zitat von Olli:
Ich habe hier niemanden gesehen, der bestritten hat, daß man den AnsiString auch als Puffer benutzen kann.
Ich hab da schon einiges Destruktives empfunden, z.B.:

Zitat von Bernhard Geyer:
Zitat von blackdrake:
Weiß denn niemand, wie ich die Inhalte eines WideStrings vorrübergehend in einen String lagern kann?
Nein, das geht nicht ohne die schon diskutierten Auswirkungen!!!!!!
Zitat von Olli:
Aber man müßte doch dann von dir erwarten können, daß du in der Lage bist den Code so zu variieren, daß es klappt
Ich habe mir alles selbst angeeignet und bin kein Programmierer. Wie soll ich dann wissen, dass man so einen Fetz machen muss? Ich habe diesmal die Idee verfolgt, in WideChar-Schritten zu arbeiten.

Zitat von Olli:
Zitat von blackdrake:
PS: Wäre doch was für die CodeLib, oder?
Lieber nicht. Es sei denn als Schaustück für eine ineffiziente Methode das besagte erreichen zu wollen
Ich find die Funktion genial, weil man damit den Speicherinhalt von WideStrings in Strings und umgekehrt kopieren kann. Wieso soll das nicht nützlich sein? Oder ist der Code unsauber?

Edit: Wie soll man denn ansonsten einen WideString mit einer String-Funktion verschlüsseln, ohne das ganze DEC mit 1,88 MB Pascal-Code umzuschreiben? Niemand hier hat mir die Lösung sagen können.

Zitat von Olli:
Zacherl's Idee klingt für mich übrigens sehr gut.

Length(ws) * sizeof(WideChar) sollte es dann ja tun ...
Was meinst du damit? Ich kann nicht über die ganze Breite den Speicher kopieren, da gibts Probleme. Deswegen war die Lösung ja, WideChar-weiße zu kopieren.

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

n/a Beiträge
 
#43

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 18:50
Zitat von blackdrake:
Binary ist nur ein anderes Wort für String. Als Kommentar ist hinterlegt, dass hier binäre Daten rein dürfen.

EncodeBinary nimmt einen binary an und übergibt dann an die Kernfunktionen (AES, BlowFish, ... -> DoEncode), die auch nur "binary" (=string) annehmen.

Bei DecodeBinary ist das genau so. Die Kernfunktionen (DoDecode) geben einen binary zurück.

Man muss also meine Funktionen verwenden, um einen WideString in einen String umzuwandeln, damit dieser verschlüsselt werden kann. Bei der Entschlüsselung würde man dann diesen Schritt wieder rückgängig machen. Und wenn es Probleme gibt, verwendet man einen Hex-String, der nicht-binär ist.
http://www.delphipraxis.net/internal...ct.php?t=85567

Zitat von blackdrake:
Ich hab da schon einiges Destruktives empfunden, z.B.:

Zitat von Bernhard Geyer:
Zitat von blackdrake:
Weiß denn niemand, wie ich die Inhalte eines WideStrings vorrübergehend in einen String lagern kann?
Nein, das geht nicht ohne die schon diskutierten Auswirkungen!!!!!!
Zugegeben, das obliegt der Interpretation. Allerdings hat Bernhard hier im Forum meines Wissens nie destruktiv reagiert

Zitat von blackdrake:
Ich habe mir alles selbst angeeignet und bin kein Programmierer. Wie soll ich dann wissen, dass man so einen Fetz machen muss? Ich habe diesmal die Idee verfolgt, in WideChar-Schritten zu arbeiten.
Habe mir auch alles selber angeeignet und nie Info studiert. Genaugenommen bin ich ein paarmal beim Infokurs durchgeflogen - zumindest bei mir zieht das als Ausrede also nicht

Zitat von blackdrake:
Ich find die Funktion genial, weil man damit den Speicherinhalt von WideStrings in Strings und umgekehrt kopieren kann. Wieso soll das nicht nützlich sein? Oder ist der Code unsauber?
Unsauber ist subjektiv, keine Ahnung. Aber definitiv ineffizient. Ich werde mal schauen, ob ich hier ein Delphi Personal zum laufen bekomme und mir das nochmal angucken. So freihand ohne Delphi ist das etwas problematisch.
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#44

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 19:00
Hallo Daniel,

ohne direkt auf API-Calls zurück zu greifen kannst du die beiden String-Typen wechselseitig so interpretieren:

Delphi-Quellcode:
// Hallo Olli - sieht ähnlich aus wie bei dir in #34!

function StringAsWideString(s: string): WideString;
begin
  SetLength(Result, Length(s) div SizeOf(WideChar));
  Move(s[1], Result[1], Length(s));
end;

function WideStringAsString(ws: WideString): string;
begin
  SetLength(Result, Length(ws) * SizeOf(WideChar));
  Move(ws[1], Result[1], Length(Result));
end;
Weil bei jeder Delphi-Funktion, die mit API String-Funktionen implementiert ist, bei NUL-Zeichen das Ende (C Konvention) eines Strings erkennt, ist tatsächlich der Weg über UTF-8 (das ist es was Bernhard dir mitteilen wollte) der schmerzfreiere:

Delphi-Quellcode:
var
  s: string;
  u: string;
  ws: WideString;

begin
  // to memphis
  s := 'Der King läbt!';
  u := AnsiToUtf8(s);
  ws := Utf8Decode(u);
  // and back
  u := Utf8Encode(ws);
  s := Utf8ToAnsi(u);
Hierbei treten keine Unverträglichkeiten auf.

Wenn du Strings in eine Datei schreibst, dann empfiehlt sich statt der Terminierung die vorgestellte Längenangabe. So können persistente Strings wesentlich effektiver verarbeitet werden.

Dein Thread ist etwas lang geraten und es kann sein, dass ich in der Mitte öfter den Faden verloren habe. Wegen etwaiger Redundanzen bitte nicht schimpfen.

Grüße vom marabu

PS: Bevor mein Beitrag völlig veraltet ist schicke ich ihn mal ab und lese dann den von Olli...
  Mit Zitat antworten Zitat
blackdrake

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

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 19:20
Hallo marabu

dass es so einfach mit deinem "StringAsWideString" geht, hätte ich nicht gedacht. Ich dachte eigentlich, ich hätte gestern alles mögliche mit [0], [1], @ und ^ ausprobiert.

Mit dem UTF 8 habe ich aber noch eine Frage: Soll ich

a) UTF8Decode und UTF8Encode
b) UTF8ToWideString und WideStringToUTF8 ( http://www.delphipraxis.net/internal...=644577#644577 )

verwenden? Bin irgendwie ein bißchen verwirrt... Ich mach jetzt vorerst mal nicht den Test mit den japanischen Zeichen. Vielleicht kannst du mir die Lösung direkt sagen, was besser ist.

Hier ein Codebeispiel:

Delphi-Quellcode:
// [url]http://www.delphipraxis.net/post644577.html#644577[/url]

function StringToWideStringEx(const S: string; CodePage: Word): WideString;
var
  InputLength,
  OutputLength: Integer;
begin
  InputLength := Length(S);
  OutputLength := MultiByteToWideChar(CodePage, 0, PChar(S), InputLength, nil, 0);
  SetLength(Result, OutputLength);
  MultiByteToWideChar(CodePage, 0, PChar(S), InputLength, PWideChar(Result), OutputLength);
end;

function WideStringToStringEx(const WS: WideString; CodePage: Word): string;
var
  InputLength,
  OutputLength: Integer;
begin
  InputLength := Length(WS);
  OutputLength := WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, nil, 0, nil, nil);
  SetLength(Result, OutputLength);
  WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, PChar(Result), OutputLength, nil, nil);
end;

function UTF8ToWideString(const S: string): WideString;
begin
   Result := StringToWideStringEx(S, CP_UTF8);
end;
function WideStringToUTF8(const WS: WideString): string;
begin
   Result := WideStringToStringEx(WS, CP_UTF8);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Utf8Decode(Utf8Encode(widestring('Täst'))) = 'Tästthen
  begin
    showmessage('OK'); // Wahr
  end;

  if widestring('Testä') = UTF8ToWideString(WideStringToUTF8(widestring('Testä'))) then
  begin
    showmessage('OK'); // Wahr
  end;
end;
EDIT: Ich sehe gerade, dass WideStringToStringEx() etwas mit den Codepages macht, was ich ja nicht will. Ich will codepageunabhängig den WideString temporär in einen String-Typ umwandeln, ohne dass Informationen verloren gehen. Ist WideStringToStringEx() dann die falsche Variante?

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

n/a Beiträge
 
#46

Re: Unicode + BASE64?

  Alt 26. Aug 2007, 19:37
Codepages sind nur wichtig wenn es um die Wandlung eines ANSI (MBCS) Strings in einen Unicode-String (oder zurück) geht. Daher ignoriere es einfach. Die Darstellung in UTF8 ist eineindeutig!

Man kann sich da leicht verhaspeln. UTF8 ist auch nur eine MBCS-Variante, aber im Gegensatz zu jenen, die eine spezifische Codepage für verschiedenen Sprachen verlangen eine eineindeutige (in beide Richtungen).

Gruß an den marabu
  Mit Zitat antworten Zitat
blackdrake

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

Re: Unicode + BASE64?

  Alt 27. Aug 2007, 02:35
Hallo.

Danke für den Hinweis.

Ich habe gerade folgende Funktionen bei Hagen als Verbesserungsvorschläge für die nächste DEC Version eingereicht. Diese erweitern DEC um die direkte WideString-Verschlüsselung ohne Umwege.

Delphi-Quellcode:
// Unit DECCipher.pas

function TDECCipher.EncodeWideString(const Source: WideString; Format: TDECFormatClass): Binary;
var
  b: binary;
begin
  try
    SetLength(b, Length(Source) * SizeOf(WideChar));
    Move(Source[1], b[1], Length(b) * SizeOf(Char));
    result := EncodeBinary(b);
  finally
    ProtectBinary(b);
  end;
end;

function TDECCipher.DecodeWideString(const Source: Binary; Format: TDECFormatClass): WideString;
var
  b: binary;
begin
  try
    b := DecodeBinary(Source);
    SetLength(result, Length(b) div SizeOf(WideChar));
    Move(b[1], result[1], Length(b));
  finally
    ProtectBinary(b);
  end;
end;

// Unit DECHash.pas

class function TDECHash.CalcWideString(const Data: WideString; Format: TDECFormatClass): Binary;
begin
  Result := CalcBuffer(Data[1], Length(Data) * sizeof(WideChar), Format);
end;

// Anmerkung: Overload
class function TDECHash.KDFx(const Data, Seed: WideString; MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary;
begin
  Result := KDFx(Data[1], Length(Data) * sizeof(WideChar), Seed[1], Length(Seed) * sizeof(WideChar), MaskSize, Format, Index);
end;
Wenn Hagen mir einen Verbesserungsvorschlag für die oben genannten Funktionen gibt, werde ich diesen Beitrag editieren.

Binary ist wie gesagt ein einfacher String. Hagen hat mir bestätigt, dass es im ganzen DEC keine Probleme mit #0 innerhalb von "binary"s gibt (er sagte was von LongString nach PChar typecasten).

Sollte ich dieses WideString Problem jedoch bei Nicht-DEC-Situationen erhalten, werde ich auf UTF8Encode() und UTF8Decode() zurückgreifen, um auf der sicheren Seite zu sein.

Danke nochmal für eure Hilfe.

War leider ein etwas langviriger Threat. Ich unterstütze zwar Unicode, aber mit Delphi ist das teilweise kompliziert und man bekommt Steine in den Weg gelegt. Borland soll ja 2008 alle offiziellen VCLs mit Unicode versehen haben (vgl. Wikipedia). Ich weiß, dass es mit TNT/TMS und EldoS auch jetzt schon geht, ist aber für ein OpenSource Projekt nicht so gut, weil die Quelltext-Betrachter/Bearbeiter dann das selbe VCL-Produkt besitzen müssen. Und TNT/TMS ist leider nicht mehr kostenlos.

Weiß jemand von euch, ob bei Delphi 2008 auch tatsächlich das WIN32 gemeint ist, oder wartet Borland, bis WIN32 tot ist und implementiert dann Unicode in WIN64? Letzteres will ich nicht hoffen.

Gruß
blackdrake

EDIT: Ressourcenschutzblöcke eingefügt, siehe Kommentar von Hagen.
Daniel Marschall
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#48

Re: Unicode + BASE64?

  Alt 27. Aug 2007, 03:17
Diese Funktionen sind auch deutlich effizienter bei der Umwandlung (dem Kopieren) der Daten!
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.186 Beiträge
 
Delphi 10.4 Sydney
 
#49

Re: Unicode + BASE64?

  Alt 27. Aug 2007, 06:07
Zitat von blackdrake:
Ich habe gerade folgende Funktionen bei Hagen als Verbesserungsvorschläge für die nächste DEC Version eingereicht. Diese erweitern DEC um die direkte WideString-Verschlüsselung ohne Umwege.
Lange Geburt aber doch Erfolgreich
Wollte gerade selbst die IDE "anschmeißen"
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#50

Re: Unicode + BASE64?

  Alt 27. Aug 2007, 09:38
Interessante Diskussion

DEC soll in seiner Schnittstelle möglichst schlank und denoch felxibel bleiben. Das ist immer ein Kompromiss der da geschlossen werden muß. Dieser Kompromiss ist notwendig da es so die Anwendungssicherheit des DECs erhöht. Die Definition Binary = type LongString wurde benutzt um darauf hinzuweisen das alle Funktionen in denen DEC diesen Datentyp benutzt in diesem String nicht darstellbare Zeichen im kompleten binären Bytebereich enthalten sein können. Der Nachteil mit der autom. Nullterminierung existiert für Delphi im Grunde garnicht. Erst ein Typcast mit PChar(String) würde dieses Problem verursachen, aber auch nur weil die PChar API Funktionen die Daten bis zum ersten #0 Zeichen auswerten und somit eine Truncation entsteht. Arbeitet man mit LongStrings mit den Delphi Bordmitteln dann wird immer mit der Längenangabe in der LongString Struktur gearbeitet.

Der Vorteil mit Binary als Datentyp zu arbeiten liegt in der direkten Kompatibilität zu Strings. Alle Vorteile die LongStrings haben gelten ach für Binary. Also Autoallokation, Reference Counting, Copy on Write Demand. Das machen die Compilermagic für uns. Binary ist also ein sehr komplexer Datentyp.

Man hätte sowas wie "array of byte" benutzen können, aber das bringt mehr Nachteile als Vorteile. Man muß ständig ein Byte-Speicherbereich in einen Char-Speicherbereich kopieren obwohl das im Grunde das gleiche ist. Bei diesen Kopierungen entstünden Performanceeinbußen und Sicherheitseinbußen da man die wichtigen Daten quasi im Speicher verteilt und somit die Kontrolle darüber immer weniger in der Hand des Entwicklers liegt.

Bestes Beipsiel die .EncodeWidestring(), .DecodeWideString() Vorschläge von oben. Man erzeugt im Speicher eine temporäre Kopie der entschlüsselten Daten, und der Programmierer hat in diesen Funtionen keinerlei Vorkehrungen getroffen vor der Freigabe dieser Variablen deren Inhalt auf sichere Art&Weise zu löschen !

Davon abgesehen enthalten alle DEC Klassen auch Methoden um mit untypisierten Datenblöcken zu arbeiten. Warum? Ganz einfach weil mit diesen eben nicht direkt unterstützte Datentypen unterstützt werden sollen. Diese Methoden heisen dann .Encode(), .Decode(), .Calc() usw.
Im Grunde besteht also garnicht die Notwengikeit umständlich durch Kopieroperationen über Datentypen hinweg das Problem zu lösen. Man könnte den WideString also auch inplaced direkt mit .Encode(WideString, WideString, Length(WideString) * 2) verschlüsseln und dann mit einem der TDECFormat Klassen umwandeln.

Das größte Sicherheitsrisiko ist immer der Anwender, und in diesem Falle wäre es der Programmierer der seine Datentypen im DEC unterstützt sehen möchte.

Das heist nicht das ich die direkte Unterstützung vom WideString im DEC als grundsätzlich falsch empfinde. Nur bisher wurde dieser Wunsch noch nie geäußert, in keiner der wohl mehr als 1000 EMails die ich zum DEC in den letzten 8 Jahren erhalten habe.

Ich denke das ich mit meinen 20 Jahren Programmiererfahrung mit Borlandprodukten sehr gut einschäzen kann welche Kompromisse ich eingehen kann und welche nicht. Das Ziel ist es doch auch weniger erfahrenen Programmiern eine Cryptolibrary anzubieten die größtenteils Anfängerfehler vermeidet. Denn genau das war eines der Unterscheidungsmerkmale zu anderen Libraries die ich für DEC haben wollte.

In den obigen Funktionen fehlt der Schutzblock

Delphi-Quellcode:
try
finally
  ProtectBinary(b);
end;
Gruß Hagen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 5 von 6   « Erste     345 6      


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 12:11 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