Frage zu AESEncoder() (Beispiel in PB-Hilfe)

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

Frage zu AESEncoder() (Beispiel in PB-Hilfe)

Beitrag von Sunny »

Also in der PB-Hilfe steht ja beim AESEncoder() folgendes Besipiel:

Code: Alles auswählen

; Sollte im Ascii-Modus kompiliert werden

String$ = "Hello this is a test for AES"

*CipheredString   = AllocateMemory(Len(String$)+1) ; Platz für den null-terminierten String
*DecipheredString = AllocateMemory(Len(String$)+1) ; mit seiner abschließenden Null (ASCII-Modus)

If AESEncoder(@String$, *CipheredString, Len(String$), ?Key, 128, ?InitializationVector)
  Debug "Ciphered: "+PeekS(*CipheredString)
  
  AESDecoder(*CipheredString, *DecipheredString, Len(String$), ?Key, 128, ?InitializationVector)
  Debug "Deciphered: "+PeekS(*DecipheredString)
EndIf

DataSection
  Key:
    Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06

  InitializationVector:
    Data.b $3d, $af, $ba, $42, $9d, $9e, $b4, $30, $b4, $22, $da, $80, $2c, $9f, $ac, $41
EndDataSection
Nun geht es mir um folgendes Kommentar darin:

"Platz für den null-terminierten String mit seiner abschließenden Null (ASCII-Modus)"

Allerdings funktioniert dieses Beispiel auch wenn ich die größe der beiden Speicher nicht um 1 erhöhe.

und StringByteLength(Chr(0)) gibt ja auch 0 zurück. Daher ist es doch eigentlich absolut unnötig oder übersehe ich da etwas?
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Frage zu AESEncoder() (Beispiel in PB-Hilfe)

Beitrag von NicTheQuick »

Die Null am Ende im Puffer '*CipheredString' ist wird ja nicht überschrieben, aber ich kann mir vorstellen, dass sie ganz praktisch für das 'Debug "Ciphered: "+PeekS(*CipheredString)' ist, damit 'PeekS()' nicht über den Speicherbereich hinaus liest.

Und die Null am Ende von '*DecipheredString' bewirkt dann natürlich das selbe. Sonst könnte es eben unter Umständen passieren, dass das 'PeekS()' in 'Debug "Deciphered: "+PeekS(*DecipheredString)' über den Speicherbereich hinaus liest. Wenn man Glück hat, ist an der Stelle aber so oder so eine Null. :wink:

Ich denke der Purifier würde meckern ohne die '+ 1'.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Frage zu AESEncoder() (Beispiel in PB-Hilfe)

Beitrag von edel »

Es ist sogar zwingend. Ist der Speicher zu klein, wird die abschliessende Null am Ende des Strings, in ein nicht reservierten Speicher geschrieben, was frueher oder spaeter zu einem "IMA" fuehrt.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Frage zu AESEncoder() (Beispiel in PB-Hilfe)

Beitrag von NicTheQuick »

Nein, es ist nicht zwingend, da der AESEnDecoder als Puffergröße nur die Länge des Strings bekommt, also 'Len(String$)' ohne die abschließende Null. Somit wird sie von ihm gar nicht erst überschrieben und an keiner Stelle in nicht reservierten Speicher geschrieben, höchstens davon gelesen durch 'PeekS()'.
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

Re: Frage zu AESEncoder() (Beispiel in PB-Hilfe)

Beitrag von Sunny »

Wie Sähe das bei einer Unicode-Executable aus, müsste ich dann " + 2" nutzen?
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Frage zu AESEncoder() (Beispiel in PB-Hilfe)

Beitrag von NicTheQuick »

Ja, aber nicht ganz. Aber ganz allgemein kannst du auch einfach '(Len(String$) + 1) * SizeOf(Character)' schreiben. Dann passt es sich automatisch an.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Frage zu AESEncoder() (Beispiel in PB-Hilfe)

Beitrag von edel »

Du hast recht, im Speicher sieht man es ganz klar. Es wird keine 0 am Ende geschrieben.
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

Re: Frage zu AESEncoder() (Beispiel in PB-Hilfe)

Beitrag von Sunny »

Ja, aber nicht ganz.
Warum nicht ganz?
Aber ganz allgemein kannst du auch einfach '(Len(String$) + 1) * SizeOf(Character)' schreiben. Dann passt es sich automatisch an.
Ja, das wusste ich schon.
auch das man nicht Len() sondern StringByteLenght() nutzen sollte, damit es nicht zu Problemen bei der Unicode-Kodierung kommt.
Es geht mir halt nur um das etwas tiefere Verständniss ^^

Das Problem ist halt nur, dass ich die Speichergröße von chr(0) nicht ermitteln kann, da das ja als das Ende eines Textes erkannt wird und z.B. StringByteLenght(chr(0)) den Wert 0 zurückliefert.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Frage zu AESEncoder() (Beispiel in PB-Hilfe)

Beitrag von NicTheQuick »

Sunny hat geschrieben:
Ja, aber nicht ganz.
Warum nicht ganz?
Weil da eben das "Len(String$) * 2" fehlte.
Sunny hat geschrieben:
Aber ganz allgemein kannst du auch einfach '(Len(String$) + 1) * SizeOf(Character)' schreiben. Dann passt es sich automatisch an.
Ja, das wusste ich schon.
auch das man nicht Len() sondern StringByteLenght() nutzen sollte, damit es nicht zu Problemen bei der Unicode-Kodierung kommt.
'StringByteLength()' ist vor allem dann wichtig, wenn man mit UTF8-Strings arbeiten will, da da jedes Zeichen verschieden lang sein kann. Bei Unicode und ASCII sind die Zeichenlänge hingegen fest.
Sunny hat geschrieben:Es geht mir halt nur um das etwas tiefere Verständniss ^^

Das Problem ist halt nur, dass ich die Speichergröße von chr(0) nicht ermitteln kann, da das ja als das Ende eines Textes erkannt wird und z.B. StringByteLenght(chr(0)) den Wert 0 zurückliefert.
Das Nullzeichen am Ende eines Strings schließt ja auch nur den String ab, es hat nichts mit dem Inhalt zu tun. Genauso gut könnte man das Nullzeichen auch komplett weg lassen und sich stattdessen merken wie lang der String ist. Deswegen gibt dir 'StringByteLenght(Chr(0))' eben auch 0 zurück, weil der String ja leer ist. Wenn du einen Beweis dafür haben willst, ob das Nullzeichen sich auch der Größe von 'Character' anpasst, dann schau mal hier:

Code: Alles auswählen

DataSection
	Label_Hallo:
	Data.s "Hallo"
	Label_Ende:
EndDataSection

Debug "Länge 'Hallo' inkl. Nullzeichen: " + Str(?Label_Ende - ?Label_Hallo)
Je nach Compilereinstellung bekommst du hier 6 oder 12 Bytes angezeigt. Das bedeutet es passt genau zur Formel '(Len("Hallo") + 1) * SizeOf(Character)'.

Um nochmals zum Verschlüsseln zurück zu kommen: Eigentlich reicht es die String selbst zu verschlüsseln und das Nullzeichen am Ende zu ignorieren.
Antworten