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 Bin2Hex - Probleme (https://www.delphipraxis.net/59463-bin2hex-probleme.html)

ichbins 22. Dez 2005 18:59


Bin2Hex - Probleme
 
Hallo, ich habe folgende Bin2Hex-Funktion geschrieben, aber die scheint nicht ganz zu funktionieren. Könnt ihr mir sagen was dabei der Fehler ist?

Hinweis: Aus z.B. i:integer=511 soll s:string='000001FF' werden.

Die Hex2Bin-Funktion schneidet vom zu lesenden String die gelesenen Bytes ab.

Delphi-Quellcode:
const
  hexes:string='0123456789ABCDEF';

function mybin2hex(const data;size:integer):string;
var
  bytes:array of byte;
  i:integer;
begin
  setlength(bytes,size);
  fillchar(bytes[0],length(bytes),#0);
  copymemory(@bytes[0],@data,size);
  result:='';
  for i:=0 to length(bytes)-1 do begin
    result:=result+hexes[1+(bytes[i] div 16)];
    result:=result+hexes[1+(bytes[i] mod 16)];
  end;
  setlength(bytes,0);
end;

//Ermitteln welchen Index der Char im String hat. (C in '0123456789ABCDEF' => 12)
function indexof(s:string;c:char):integer;
var
  i:integer;
begin
  result:=0;
  for i:=1 to length(s) do
    if s[i]=c then
    begin
      result:=i;
      exit;
    end;
end;

procedure myhex2bin(var data; hex:string; const size:integer);
var
  bytes:array of byte;
  i:integer;
  workwith:string;
begin
  workwith:=copy(hex,1,size*2);
  hex:=copy(hex,size*2,length(hex)-size*2);
  setlength(bytes,length(workwith) div 2);
  for i:=0 to (length(workwith) div 2)-1 do
    bytes[i]:=indexof(hexes,workwith[i*2])*16+indexof(hexes,workwith[i*2+1]);
  copymemory(@data,@bytes,length(bytes));
  setlength(bytes,0);
end;
In Realität kommen aber lauter falsche Werte raus (jedes mal dasselbe, hex2bin schneidet String nicht ab)

marabu 22. Dez 2005 21:13

Re: Bin2Hex - Probleme
 
Hallo Michael,

Zitat:

Zitat von ichbins
Die Hex2Bin-Funktion schneidet vom zu lesenden String die gelesenen Bytes ab.

Wo macht sie das denn? Kennst du den Unterschied von call-by-value und call-by-reference?

Du kannst deine Konstante HEXES ruhig aus den Prozeduren heraus nehmen - eine Konstante reicht für beide Prozeduren. Und wenn du dich ein wenig anstrengst, dann kommst du auch ohne zusätzliche lokale Variablen (bytes, workwith) aus. Deine Funktion IndexOf ist viel zu teuer für ihren Zweck - mach es besser inline. Vielleicht schaffst du es auch die mehrfache Berechnung des selben Wertes (Length(worklist) div 2) zu vermeiden.

Grüße vom marabu

ichbins 23. Dez 2005 12:42

Re: Bin2Hex - Probleme
 
Das wäre die Optimierung, aber ich wäre auch schon glücklich wenn es überhaupt funktioniert...

marabu 23. Dez 2005 13:19

Re: Bin2Hex - Probleme
 
Hallo Michael,

meinen wichtigsten Hinweis hast du einfach überlesen - call by reference ist notwendig, wenn du abschneiden willst. Beachte das var Schlüsselwort in der Signatur. Die lokalen Zwischenspeicher habe ich eliminiert und die nibble Berechnung als inline code aufgenommen.

Delphi-Quellcode:
const
  HEX_DIGITS: string = '123456789ABCDEF0';

procedure myhex2bin(var data; var hex: string; const size: integer);
var
  bin: PByte;
  i: integer;
begin
  bin := @data;
  for i := 1 to size do // Length(hex) durch size ersetzt
  begin
    bin^ := (Pos(hex[Pred(i shl 1)], HEX_DIGITS) mod 16) shl 4
          + (Pos(hex[i shl 1], HEX_DIGITS) mod 16);
    Inc(bin);
  end;
  Delete(hex, 1, size shl 1);
end;
Grüße vom marabu


EDIT: Sorry - die Schleife muss natürlich bei size terminieren.

ichbins 23. Dez 2005 13:54

Re: Bin2Hex - Probleme
 
* einbau *

-> Fehler:

Delphi-Quellcode:
for i := 1 to Length(hex) do
müsste heissen
Delphi-Quellcode:
for i := 1 to Length(hex) div 2 do
aber irgendwie wills trotzedm noch nicht klappen :wall:
Delphi-Quellcode:
var
  s,s2:string[255];
  x:string;
begin
  s:='My name is methos.';
  x:=mybin2hex(s,255);
  myhex2bin(s2,x,255);
  showmessage('Myhex2bin(mybin2hex(''My name is methos'')) = '+s2);
==> '^Š1r~v1z„1~v…yp„?' :gruebel: is irgendwie nicht das Ergebniss...

//edit: wenn ich normale Ansistrings (<>string[x]) verwende, krieg ich eine AV :wall:

Khabarakh 23. Dez 2005 14:12

Re: Bin2Hex - Probleme
 
Zitat:

Code:
result:=result+hexes[[b]1+[/b](bytes[i] mod 16)];

Hier hast du berücksichtigt, dass Delphi-Strings 1-indiziert sind.
Gut.
In bin2hex allerdings nicht mehr :wink:
Code:
bin^ := ((Pos(hex[Pred(i shl 1)], hexes) mod 16) [b]- 1[/b]) shl 4
          + ((Pos(hex[i shl 1], hexes) [b]- 1[/b]) mod 16);
So funktioniert es perfekt.

ichbins 23. Dez 2005 14:15

Re: Bin2Hex - Probleme
 
muss ich dann für real-Variablen etc. eine 2. Funktion schreiben?

Bei reals geht's auchnicht :wall:

123.456 -> 1,93844495467899E84

Khabarakh 23. Dez 2005 14:25

Re: Bin2Hex - Probleme
 
:gruebel: Nein. Es geht doch nicht um den Argumenttyp, sondern um deine Konstante, die eben ein Delphi-String ist. Wenn im Hexstring beispielsweise '0' steht, gibt Pos 1 zurück und so steht es dann auch in data.

ichbins 23. Dez 2005 14:26

Re: Bin2Hex - Probleme
 
achso, jetzt verstehe ich :oops:

Und stimmt die erste Funktion (bin2hex)?

//edit: JUPPIE JUCHUUU!!!! (funzt)

//edit2: Vieeelen Dank an alle :thumb: :thumb: :thumb: (brauch ich nämlich bis morgen, 3x dürft ihr raten wofür :xmas: )

Khabarakh 23. Dez 2005 14:35

Re: Bin2Hex - Probleme
 
Du könntest höchstens noch
Delphi-Quellcode:
result:=result+hexes[1+(bytes[i] div 16)];
result:=result+hexes[1+(bytes[i] mod 16)];
durch
Delphi-Quellcode:
result:=result+hexes[1+(bytes[i] shr 4)];
result:=result+hexes[1+(bytes[i] and $F)];
ersetzen :wink: .


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:21 Uhr.
Seite 1 von 2  1 2      

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