Autor Beitrag
Nothilvien
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Di 11.11.08 18:27 
Hallo, also ich habe folgende 2 Funktionen, die ich umschreiben moechte.
undzwar so, dass sie genau das gegenteil tun (also wieder zurueck)
ich brauche folgende funktionen, da ich daten durch ein winsock bekomme, diese
werden somit erst in einen bin array gewandelt, und diese dan in HEX code.
Das funktioniert auch alles ganz super =)

nur muss ich die daten ja auch irgendwie weider zurück schicken, dazu muss ich nuneinmal
den HEX code wieder in einen binarray und diesen wieder in ein Widestring.

diese funktionen habe ich aus dem internet gegooglet, daher bin ich mir über
was dadrinne eigentlich passiert nicht genau bewusst.

z.B. was macht das "@" symbol?

das widestringtobinarray verstehe ich ja noch in etwa..
zuerst wird der array auf die passende laenge gesetzt mit setlengh
und dann wird der widestring byte fuer byte in den array geschrieben?
mhm..so in ewta sollte das ablaufen glaube ich.

und was bei der anderen umwandlung mit MOD & DIV passier..weis ich leider nicht :S

hier sind einmal die 2 funktionen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure WideStringToBinArray(const ws: WideString; var bin: TBinArray);
var
  l: Integer;
begin
  l := Length(ws)*SizeOf(WideChar);
  SetLength(bin, l);
  CopyMemory(@bin[0], @ws[1], l);
end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
Function ByteToString (b: BYTE): STRING;
const
NIBBLECHAR:
ARRAY[$0..$FOF CHAR

= ('0','1','2','3','4','5','6','7',

'8','9','A','B','C','D','E','F');

VAR s: STRING;

begin

SetLength(s,2);
s[1] := NIBBLECHAR[b DIV 16];
s[2] := NIBBLECHAR[b MOD 16];
Result := '$'+s

end;


ich bin fuer jeden kleinen denkanstoss & hilfe dankbar
-noth
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 11.11.08 18:31 
Zunächst einmal:
@ gibt dir die Adresse der Variablen vor die du es schreibst.
x mod y berechnet den Rest der Division x / y, div den ganzzahligen Anteil des Ergebnisses (also eben ohne Nachkommastellen als Integer). Beide Operatoren sind nur für Integeroperanden möglich.

Die Funktionen schaue ich mir an, die Umkehrungen tippe ich besser nicht einfach ohne Test ;-).

// EDIT:
Als Umkehrung der zweiten Funktion sollte schlicht IntToStr gehen.
Nothilvien Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Di 11.11.08 21:50 
oh yay ;D

ya IntToStr ist guuuuut

ala

ausblenden Delphi-Quelltext
1:
Showmessage(inttostr($11));					


Das $ bewirkt das delphi es als hex wert inteprtiert ^.^
das ist klasse! :o

so kann ich dan mit einer schleife schonmal die 2.Funktion rueckwerts machen.
ich versuche mich erstmal daranne =) -wenn ichs hab poste ichs hoho *freu*
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 11.11.08 23:05 
Und für die Hexdarstellung hat Delphi auch die eingebaute Funktion IntToHex ;-), du musst nur das $ davorschreiben, damit Delphi es auch als Hexdarstellung erkennt, wenn du es danach an IntToStr fütterst.

Zur ersten Funktion:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure BinArrayToWideString(const bin: TBinArray; var ws: WideString);
var
  l: Integer;
begin
  l := Length(bin) div SizeOf(WideChar);
  SetLength(ws, l);
  CopyMemory(@ws[1], @bin[0], Length(bin));
end;
Ich habe das jetzt doch nicht getestet (ich habs vorhin vergessen :oops:) und hab eben einfach mal Ziel und Quelle vertauscht, aber ich denke mal das sollte stimmen.
Nothilvien Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Di 11.11.08 23:38 
hey danke dir, mach dir ja keinen stress, ich habe zeit =)
das programmeiren mache ich hobbymaessig und versuche soviel zu lernen und kapieren wie s geht^^

den code hextoint werd ich gleich mal testen(und das mit dem getauschten quellen auch), aber ich muss morgen füh raus daher verabschiede ich mich ersteinmal, werde das heir dan edetieren wenn ich morgen nach hause komme.



-noth
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 11.11.08 23:51 
Neue Infos nach einiger Zeit musst du nicht editieren, auch wenn noch nicht 24 Stunden herum sind, denn wenn dein letzter Beitrag schon eine Weile da war dann merken viele ja nichts vom Editieren. Deshalb kannst du dann ruhig normal eine neue Antwort erstellen, damit man davon etwas mitbekommt.

Nur reine Schiebepostings ohne wirklich neue Informationen, die nur zum Hochholen des Threads dienen (*push* und so), sind hier erst nach 24 Stunden erlaubt. ;-)
Nothilvien Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Mi 12.11.08 19:07 
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
//Anzahl
function Zeichen(const s: Stringconst z: Char): Integer;
var
  I: Integer;
begin
result := 0;
for I := 1 to length(s) do
  if s[i] = z then inc(result);
end;



//Splitt
function Split(TempString,Delimiter : String; StrIndex : Integer) : String;
var
  CurrIndex : Integer ;
begin
  TempString:=TempString + Delimiter;
  if Pos(Delimiter,TempString)<>0
  then
begin
  CurrIndex:=1;
  while StrIndex>CurrIndex
  do
begin
  TempString:=Copy( TempString,
  Pos(Delimiter,TempString)+Length(Delimiter),
  MaxInt
  );
  Inc(CurrIndex);
end;
  Result:=Copy(TempString,0,Pos(Delimiter,TempString)-1);
end;
end;


//das was ich produziert habe x.x"
procedure HexToByte(var h: stringvar Hex: array of string);
var
i:integer;
begin
i:=0;
for i := 0 to zeichen(h,'$'do //halt so oft wie $ vorhanden ist, da jedes $ fuer einen hex wert steht.
//showmessage(inttostr(zeichen(h,'$')));
Hex[i] := Split(h,'$',i); //fuelle den array mit dem hex werten. nach dem 0ten $, nach dem 1sten etc..
//showmessage(Split(h,'$',i-3));
// showmessage(hex[3]);
end;




//zum testen
procedure TForm2.Button1Click(Sender: TObject);
var StringArray: array [0..9of string;
test:string;
begin
test:= '$aa$bb$cc$dd';

HexToByte(test,StringArray);
Showmessage(StringArray[0]);
Showmessage(StringArray[1]);
Showmessage(StringArray[2]);
end;


er zeigt mir an das im stringarray[2] = AA drinne ist, aber wieso nicht bei stringarray[0]?
immerhin faengt er doch mit 0 an zu zaehlen.

er faengt aber erst an bei [2] zu faellen also [3] = BB

die funktion Zeichen & Splitt habe ich aus dem netz und sie tun eigentlich beide ihre sache.
procedure HexToByte habe ich selbst geschrieben,
sie soll einen string den ich ihr gebe (der hexadecimale..$AA$BB$CC..)
in einen array speichern so das stringarray[0] = AA ist,
damit ich spaeter mit inttostr('$' + stringarry[i]) mit einer schleife die hexa umwandeln kann.
jedenfalls habe ich mir das so gedacht, aber er mag ja ncihteinmal den array richtig befuellen ;S

ach ja und das mit ziel&Quelle vertauschen klappt wunderbar!!

nur noch das 2te, bytetostring bekomm ich nciht so richtig hin :S also das es
string2byte macht (also den hex string als byte & und dan jedes byte in den array, damit ich die 2.umkehr funktion damit benutzen kann.

//Edit:

hoho habs,
ausblenden Delphi-Quelltext
1:
Hex[i] := Split(h,'$',i+2);					


ich hatte mich vage daran erinnert, das bei der split funktion n comment war wo stand das sie bei -2 oder so wegen kompatiblitaet?? oder so startet, weis nicht, wen sich eien funktion gut bewaehrt speichere ic hsie mir gern *g* mit der zeit vergisst man dan schonmal etwas darüber ^^"

nja mal scahuen das ich weiterkomme ;D
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 12.11.08 22:47 
Da du ja immer eine feste Länge von zwei Buchstaben nach dem Zeichen für hexadezimal hast wäre es deutlich schneller wenn du direkt mit dem String arbeitest statt das Splitten und Zählen von eigenständigen Funktionen zu machen und das Splitten praktisch immer zu wiederholen. ;-)
Nothilvien Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Do 13.11.08 00:48 
jap, hast du recht, ich denke das ich dan einfach immer 3 symbole kopieren kann, dan die 3 leoschen und die naechsten 3 etc..oder so, mal sehen, optimieren werde ich spaeter ich moechte ersteinmal das es funktioniert^^

naja das empfangen geht wunderbar, nur das senden nicht grr >.<
aber ich glaube dafuer sollte ich lieber ein neuen thread aufmachen, da es glaube hier nicht hingehoert x.x!

danke ^-^!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 13.11.08 01:22 
Soo, ich hab mich mal kurz drangesetzt und ne kleine optimierte Variante geschrieben, ich hab das jetzt einfach so hingetippt, aber das sollte so gehen.
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
procedure TFormX.ButtonXClick(Sender: TObject);
type
  TBinArray = array of Byte;

  procedure HexToBinArray(const Src: Stringvar Bytes: TBinArray);

    function CharValue(const Value: Char): Byte;
    begin
      case Value of
        '0'..'9': Result := Ord(Value) - 48;
        'a'..'f': Result := Ord(Value) - 87;
        'A'..'F': Result := Ord(Value) - 55;
      end;
    end;

  var
    i: Integer;
  begin
    SetLength(Bytes, Length(Src) div 3);
    for i := 0 to Length(Bytes) - 1 do
      Bytes[i] := CharValue(Src[i*3 + 2]) * 16 + CharValue(Src[i*3 + 3]);
  end;

var
  Test: TBinArray;
begin
  HexToBinArray('$0a$A0$10', Test);
  ShowMessage(IntToStr(Test[0]));
  ShowMessage(IntToStr(Test[1]));
  ShowMessage(IntToStr(Test[2]));
end;
Was passiert ist, dass einfach immer der zweite und dritte Buchstabe eines Dreierpacks von Buchstaben direkt verrechnet werden. Bei Fragen frag ruhig ;-).
Nothilvien Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Do 13.11.08 01:46 
Also:
CharValue

schaut nach zu welcher von den 3 gruppen der char gehoert und gbt als ergebnis, seine ordnungszahl minus die jeweils fuer die gruppe festgelegte anzahl, aus.

So wuerde ich das auffasen, bin mir aber nicht sciher, und ehrlich gesagt weis ich nciht wirklich was das bringt ;D

naja zum2. teil:
zuerst wird die groesse des binären arrays festgelegt auf die lenge des eingangs strings ganzzahlig geteilt durch 3.
damit wir wissen, wieviele 3er ketten im string sind. und wie oft die schleife durchlaufen muss.

dan wird der binäre array solange mit den öhhm..."binären werten gefüllt" bis er voll ist :P

eh ja genau^^ die interne funktion verstehe ich nicht ganz, aber ich denke das ist die wichtigste zeile,
die das ganze umwandeln durchführt, sowie dazu dient immer die passenden 3 segmente aus dem string auszuwerten.

ach ja, vielen lieben dank dir *.*!
Wenn du lehrer wirst werden sich die schüler fruen, wenn du ihnen alles vortippst ^.^ bist voll nett (:

mache mich nun offline~ byebye
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 13.11.08 02:56 
Also zur Erklärung:
ausblenden Delphi-Quelltext
1:
2:
case Value of
        '0'..'9': Result := Ord(Value) - 48;
48 ist der Asciicode von '0', Ord gibt den des Zeichens in Value zurück. Also, zum Beispiel mit Zeichen '0' in Value:
Ord('0') - 48 = 48 - 48 = 0
Zeichen '1':
Ord('1') - 48 = 49 - 48 = 1
Zeichen 'a':
Ord('a') - 87 = 97 - 87 = 10
Auf diese Weise wird also aus dem Zeichenwert im Asciicode der Wert des entsprechenden hexadezimalen Zeichens berechnet.

ausblenden Delphi-Quelltext
1:
Bytes[i] := CharValue(Src[i*3 + 2]) * 16 + CharValue(Src[i*3 + 3]);					
Die linke Stelle des hexadezimalen Wert ist ja die 16er Stelle, also muss der Wert an dieser Stelle mit 16 multipliziert werden, die rechte Stelle wird dazu addiert.
25 dezimal = 2 * 10 + 5
25 hexadezimal = 2 * 16 + 5
;-)

i*3 --> das i-te 3er Pack an Buchstaben
das erste Zeichen eines Strings ist 1, nicht 0, also +1
das erste Zeichen ist das $, also geht es um das nächste Zeichen, nochmal +1
--> i*3 + 2 ist die erste Stelle jeweils
i*3 + 3 dementsprechend das zweite