Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Universale ToHex und FromHex procedure/function (https://www.delphipraxis.net/87756-universale-tohex-und-fromhex-procedure-function.html)

yankee 5. Mär 2007 19:15


Universale ToHex und FromHex procedure/function
 
Hi @ll,

ich habe diese Funktionen geschrieben um ein set of xy abzuspeichern, aber eigentlich müssten diese Funktionen mit jedem "normalen" Datentyp funktionieren:+

Delphi-Quellcode:
function ToHex(data: PChar; bytes: integer):string;
var i: integer;
    res: string;
begin
  setlength(res, bytes*2);
  res :='';
  for i:=1 to bytes do
  begin
    res :=res+IntToHex(byte(data^),2);
    inc(data);
  end;
  result :=res;
end;

procedure FromHex(data: PChar; hex: string);
var i: integer;
begin
  for i:=0 to length(hex) div 2-2 do
  begin
    if i>=1 then inc(data);
    data^ :=char(StrToInt('$'+hex[i*2+1]+hex[i*2+2]));
  end;
end;
Anwendungsbeispiel:
Delphi-Quellcode:
procedure Beispiel;
var str: string;
    aSet; set of byte;
begin
  aSet :=[1,2,3,109,250];
  str :=ToHex(@aSet,sizeof(aSet));

  //Jetzt kann man str gemütlich in einer Datei speichern und später wieder laden:

  FromHex(@aSet,str);
end;
Natürlich solltet iohr gewarnt sein, dass man sich mit diesen zwei Funktionen auch was kaputt machen kann, wenn beispielsweise byte inkorrekt übergeben wurde oder man versucht mit FromHex In eine Variable zu schreiben, die zu klein ist um die Daten aufzunehmen.
Ausserdem könnt ihr die Funktion natürlich nur auf Variabeln anweden, die hintereinander weg im ram sind. Das auf ein Objekt anzuwenden könnte lustige Effekte haben.
Ausserdem bewart euch diese Funktion auch nicht vor Inkompatibilitäten zwsischen Systemen. Ein integer auf einem 64bit-System hat... naja... eben 64 bit und auf einem 32 bitsystem nur 32. Beim Speichern von einem Integer auf 64 bit und laden auf 32 bit kann also auch lustige Effekte haben. Umgekehr natürlich genauso, nur dass ihr umgekehrt wahrscheinlich deutlich länger brauchen werdet, bis ihr den Bug gefunden habt.

Aber wenn ihr wisst, was ihr tut, könnten diese zwei Funktionen durchaus nützlich sein :-).

sirius 5. Mär 2007 19:53

Re: Universale ToHex und FromHex procedure/function
 
Bist du dir sicher, dass das funktioniert?

Erstmal sinnloses Streichen:
Delphi-Quellcode:
setlength(res, bytes*2);
res :=''; //ist nix anders als setlength(res,0);
Eins von beiden ist sinnlos. (die erste Variante ist für die Perfomance der restlichen Funktion besser, allerdings müsste man dann den Rest auch ändern)
Delphi-Quellcode:
if i<bytes then inc(data);
Das if kann raus, die Schleife wird eh beendet und dem Zeiger ist es egal wohin er zeigt.

Was ich aber überhaupt nicht verstehe ist das hier:
Delphi-Quellcode:
IntToHex(byte(data^),2)
Du weist schon, wie ein set abgespeichert wird? in deinem Fall ist es 32 Byte lang und jedes Bit entspricht einem Wert. Und dieses Bit ist eben gesetzt oder nicht gesetzt.

Deswegen verstehe ich nicht, was du vor hast. Abgesehen davon, dass du mit deinem data-Zeiger viel zu weit rennst.

Hawkeye219 5. Mär 2007 19:58

Re: Universale ToHex und FromHex procedure/function
 
Hallo,

Delphi bietet in der Unit Classes die Routinen Delphi-Referenz durchsuchenBinToHex und Delphi-Referenz durchsuchenHexToBin an.

Gruß Hawkeye

yankee 5. Mär 2007 20:05

Re: Universale ToHex und FromHex procedure/function
 
Zitat:

Zitat von sirius
Bist du dir sicher, dass das funktioniert?

Ja
Zitat:

Zitat von sirius
Delphi-Quellcode:
setlength(res, bytes*2);
res :=''; //ist nix anders als setlength(res,0);
Eins von beiden ist sinnlos. (die erste Variante ist für die Perfomance der restlichen Funktion besser, allerdings müsste man dann den Rest auch ändern)

Naja gut... Da habe ich durch Delphis Management von string immernoch nicht durchgestiegen... Ich will ja einen string, der schonmal für x Zeichen Speicher holt, aber der String sollte erstmal leer sein...
Zitat:

Zitat von sirius
Delphi-Quellcode:
if i<bytes then inc(data);
Das if kann raus, die Schleife wird eh beendet und dem Zeiger ist es egal wohin er zeigt.

jo, ok ;-).
Zitat:

Zitat von sirius
Was ich aber überhaupt nicht verstehe ist das hier:
Delphi-Quellcode:
IntToHex(byte(data^),2)
Du weist schon, wie ein set abgespeichert wird? in deinem Fall ist es 32 Byte lang und jedes Bit entspricht einem Wert. Und dieses Bit ist eben gesetzt oder nicht gesetzt.

Ja... Und wo ist jetzt das Problem? Du hast aber schon verstanden, was meine funktion da macht, ne? Und wie der ram so aufgebaut ist usw. usw.?

Zitat:

Zitat von sirius
Deswegen verstehe ich nicht, was du vor hast. Abgesehen davon, dass du mit deinem data-Zeiger viel zu weit rennst.

Das sehe ich erstmal anders...
Ich bin ja für Kritik und änderungsvorschläge durchaus aufgeschlossen, aber der Satz sagt nur "irgendwie verstehe ich das alles nicht und daher... daher ist das falsch" :-).
Zitat:

Zitat von Hawkeye219
Hallo,

Delphi bietet in der Unit Classes die Routinen Delphi-Referenz durchsuchenBinToHex und Delphi-Referenz durchsuchenHexToBin an.

Ja, die Funktionen habe ich auch versucht zu verwenden, bevor ich sie mir selbst geschrieben habe.
Nur haben dir mir immer einfach irgendwelche Exceptiosn geworfen, die ich nicht nachvollziehen konnte.

Hawkeye219 5. Mär 2007 20:18

Re: Universale ToHex und FromHex procedure/function
 
Zitat:

Zitat von yankee
Ja, die Funktionen habe ich auch versucht zu verwenden, bevor ich sie mir selbst geschrieben habe.
Nur haben dir mir immer einfach irgendwelche Exceptiosn geworfen, die ich nicht nachvollziehen konnte.

In Anlehnung an deine Routinen könnte man sie so kapseln:

Delphi-Quellcode:
function Bin2Hex (const Data; Size: Cardinal): string;
begin
  SetLength (Result, 2 * Size);
  BinToHex (@Data, PChar(Result), Size);
end;

procedure Hex2Bin (const s: string; var Data);
begin
  HexToBin(PChar(LowerCase(s)), @Data, Length(s) div 2);
end;
Gruß Hawkeye

yankee 5. Mär 2007 20:25

Re: Universale ToHex und FromHex procedure/function
 
Zitat:

Zitat von Hawkeye219
In Anlehnung an deine Routinen könnte man sie so kapseln:

Delphi-Quellcode:
function Bin2Hex (const Data; Size: Cardinal): string;
begin
  SetLength (Result, 2 * Size);
  BinToHex (@Data, PChar(Result), Size);
end;

procedure Hex2Bin (const s: string; var Data);
begin
  HexToBin(PChar(LowerCase(s)), @Data, Length(s) div 2);
end;
Gruß Hawkeye

Ähm... jooo... das funktioniert ^^.
Jetzt frag ich mich ja schon, was ich eben falsch gemacht habe, aber ich würde sagen, damit kann man das Thema voll getrost vergesse ;-).

sirius 5. Mär 2007 20:26

Re: Universale ToHex und FromHex procedure/function
 
Ich bin in der Annahme, dass nach der Funktion ToHex bei deinem Beispiel am Ende folgender String stehen soll: "0102036DFA". Den Nutzen habe ich dann auch noch nicht verstanden, aber egal. vielleicht übersehe ich da noch etwas. Auf jeden Fall kommt das Ergebnis bei dir nicht heraus, sondern (jetzt hab ichs mal getestet): "0E00000000000000000000000020000000000000000000000 000000000000004"
Dein Data rennt nicht zu weit, denn sizeof gibt nicht 256 zurück (wie ich dachte) sondern tatsächlich 32 Bytes.

Was du also machst, ist ein set in einer Form zurückzugeben, die entweder nicht dem entspricht, was du wolltest, oder ich verstehe den Sinn nicht.

Das zurücksetzen klappt. Allerdings, kannst du hier auch das if sparen, wenn du das inc hinter die andere Anweisung setzt.

yankee 5. Mär 2007 20:34

Re: Universale ToHex und FromHex procedure/function
 
Zitat:

Zitat von sirius
Ich bin in der Annahme, dass nach der Funktion ToHex bei deinem Beispiel am Ende folgender String stehen soll: "0102036DFA". Den Nutzen habe ich dann auch noch nicht verstanden, aber egal.

Ja, davon würde ich den Sinn auch nicht verstehen, aber das ist ja auch garnicht Sinn der Sache :-P.

Zitat:

Zitat von sirius
Auf jeden Fall kommt das Ergebnis bei dir nicht heraus, sondern (jetzt hab ichs mal getestet): "0E00000000000000000000000020000000000000000000000 000000000000004"

Absolut richtig und erwarted...
Kannst du mir mal sagen, wie man auf was anderes kommen soll??
Zitat:

Zitat von sirius
Dein Data rennt nicht zu weit, denn sizeof gibt nicht 256 zurück (wie ich dachte) sondern tatsächlich 32 Bytes.

Nö, aber wenn ich dich zitieren darf: Ein set ist ein bitfeld. 1 Byte sind 8 Bit... Und sizeof gibt immer die grösse in Bytes zurück (hast du jemald sizeof verwendet?^^). Du kannst aj nicht weniger als 1 Byte Speicher allocaten...

Zitat:

Zitat von sirius
Was du also machst, ist ein set in einer Form zurückzugeben, die entweder nicht dem entspricht, was du wolltest, oder ich verstehe den Sinn nicht.

Ich hab's doch drangeschrieben: Zum Speichern eines sets in einem string. Was kann man den daran nicht verstehen...?

Zitat:

Zitat von sirius
Das zurücksetzen klappt.

Das "hinsetzen" übrigens auch :-).
Zitat:

Zitat von sirius
Allerdings, kannst du hier auch das if sparen, wenn du das inc hinter die andere Anweisung setzt.

Hast recht, aber Hawkeye219 hat das Thema ja jetzt eh überflüssig gemacht.

sirius 6. Mär 2007 08:02

Re: Universale ToHex und FromHex procedure/function
 
Zitat:

Ja, davon würde ich den Sinn auch nicht verstehen, aber das ist ja auch garnicht Sinn der Sache .
Naja, wenn ich eine Funktion toHex aufrufe, dann erwarte ich, dass meine Eingangszahlen hinten als Hex herauskommen und nicht das irgendetwas als Hex heraus kommt (auch wenn es eineindeutig ist).

Zitat:

Kannst du mir mal sagen, wie man auf was anderes kommen soll??
Einfach statt 64Bytes, 32 Bytes verwenden, so wie es das Set auch benötigt :mrgreen:

Zitat:

Ich hab's doch drangeschrieben: Zum Speichern eines sets in einem string. Was kann man den daran nicht verstehen...?
Also das war dein sinn? Und warum hast du da (abgesehen von den tausend anderen Varianten) nicht einfach das Zeichen abgespeichert, was du unter pchar gefunden hast:
Delphi-Quellcode:
function SetToString(data: PChar; bytes: integer):string;
var i: integer;
begin
  setlength(result, bytes);
  for i:=1 to bytes do
  begin
    result[i]:=data^;
    inc(data);
  end;
end;
:gruebel:

oder einfach so:
Delphi-Quellcode:
function SetToString(const data; bytes: integer):string;
begin
  setlength(result, bytes);
  move(data,result[1],bytes);
end;

Hawkeye219 6. Mär 2007 08:36

Re: Universale ToHex und FromHex procedure/function
 
Hallo sirius,

Zitat:

Also das war dein sinn? Und warum hast du da (abgesehen von den tausend anderen Varianten) nicht einfach das Zeichen abgespeichert, was du unter pchar gefunden hast
yankee möchte mit den vorgestellten Routinen beliebige binäre Daten in eine Textform überführen, um sie anschließend beispielsweise in einer .ini-Datei abzuspeichern. Delphi geht beim Speichern der .dfm-Dateien ähnlich vor. Öffne einfach mal die .dfm-Datei eines Formulars, welches ein TImage enthält, mit einem Texteditor.

Gruß Hawkeye


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:44 Uhr.
Seite 1 von 2  1 2      

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