Verwirrung bzgl. Unicode/Ascii bei PeekS()
Verfasst: 19.11.2015 02:32
Hallo,
ich habe hier eine Testprozedur die folgendes mit einem String macht:
1) Den String AES verschlüsseln
2) Das Ergebnis aus 1) dann Base64 kodieren
3) Den Base64 kodierten String wieder Base64 dekodieren
4) Den aus 3) dekodierten Speicherblock wieder AES entschlüsseln
Also einen String verschlüsseln, kodieren und dann alles wieder Rückwarts so, dass der originale String wieder hergestellt ist.
Das ganze sollte mal im Unicode-Modus und mal im Ascii-Modus kompiliert werden.
Es gibt in der Prozedur folgende relevanten Debugausgaben:
Hier wird der wiederhergestellte String auf sechs verschiedene Arten aus dem Memory gepeekt.
1) Im Unicode-Modus ohne Angabe einer Stringlänge
2) Im Unicode-Modus mit Angabe einer Stringlänge
3) Im Ascii-Modus ohne Angabe einer Stringlänge
4) Im Ascii-Modus mit Angabe einer Stringlänge
5) Ohne Modusvorgabe und ohne Angabe einer Stringlänge
6) Ohne Modusvorgabe und mit Angabe einer Stringlänge
Was mich verwirrt ist, dass die Ausgaben im Modus Unicode und Ascii nur dann funktionieren, wenn explizit die Länge des auszuPEEKenden Strings mit angegeben wird. Und das, obwohl das Programm im entsprechenden Modus (Unicode / Ascii) kompiliert wurde.
Einzig die beiden Ausgaben ohne die explizite Angabe von #PB_Ascii oder #PB_Unicode geben auch ohne eine Längenangabe immer den korrekten String aus.
Warum ist das so? Ich dachte, dass ich mit der Programmierung im Unicode-Modus und der expliziten Angabe von #PB_Unicode zukunftssicher bin. So ganz sicher in ich mir jetzt bzgl. dieser expliziten Angabe von #PB_Unicode nicht mehr.
Wie muss ich das in meinem Beispiel handhaben, damit der Code auch in zukünftigen PB Versionen läuft?
Hier der Testcode:
ich habe hier eine Testprozedur die folgendes mit einem String macht:
1) Den String AES verschlüsseln
2) Das Ergebnis aus 1) dann Base64 kodieren
3) Den Base64 kodierten String wieder Base64 dekodieren
4) Den aus 3) dekodierten Speicherblock wieder AES entschlüsseln
Also einen String verschlüsseln, kodieren und dann alles wieder Rückwarts so, dass der originale String wieder hergestellt ist.
Das ganze sollte mal im Unicode-Modus und mal im Ascii-Modus kompiliert werden.
Es gibt in der Prozedur folgende relevanten Debugausgaben:
Code: Alles auswählen
Debug "AESDecoded Unicode ohne Länge: '"+PeekS(*AESDecodedString, #PB_Unicode)+"'"
Debug "AESDecoded Unicode mit Länge : '"+PeekS(*AESDecodedString, AESDecodedLength, #PB_Unicode)+"'"
Debug "AESDecoded Ascii ohne Länge : '"+PeekS(*AESDecodedString, #PB_Ascii)+"'"
Debug "AESDecoded Ascii mit Länge : '"+PeekS(*AESDecodedString, AESDecodedLength, #PB_Ascii)+"'"
Debug "AESDecoded Nix ohne Länge : '"+PeekS(*AESDecodedString)+"'"
Debug "AESDecoded Nix mit Länge : '"+PeekS(*AESDecodedString, AESDecodedLength)+"'"
1) Im Unicode-Modus ohne Angabe einer Stringlänge
2) Im Unicode-Modus mit Angabe einer Stringlänge
3) Im Ascii-Modus ohne Angabe einer Stringlänge
4) Im Ascii-Modus mit Angabe einer Stringlänge
5) Ohne Modusvorgabe und ohne Angabe einer Stringlänge
6) Ohne Modusvorgabe und mit Angabe einer Stringlänge
Was mich verwirrt ist, dass die Ausgaben im Modus Unicode und Ascii nur dann funktionieren, wenn explizit die Länge des auszuPEEKenden Strings mit angegeben wird. Und das, obwohl das Programm im entsprechenden Modus (Unicode / Ascii) kompiliert wurde.
Einzig die beiden Ausgaben ohne die explizite Angabe von #PB_Ascii oder #PB_Unicode geben auch ohne eine Längenangabe immer den korrekten String aus.
Warum ist das so? Ich dachte, dass ich mit der Programmierung im Unicode-Modus und der expliziten Angabe von #PB_Unicode zukunftssicher bin. So ganz sicher in ich mir jetzt bzgl. dieser expliziten Angabe von #PB_Unicode nicht mehr.
Wie muss ich das in meinem Beispiel handhaben, damit der Code auch in zukünftigen PB Versionen läuft?
Hier der Testcode:
Code: Alles auswählen
EnableExplicit
Procedure.s Encode(sKey.s, sInitVector.s, sText.s)
Protected.i *AESEncodedString, *AESDecodedString, *B64EncodedString, *B64DecodedString
Protected.i AESEncodedLength, AESDecodedLength, B64EncodedLength, B64DecodedLength
If Len(sKey) < 32
sKey + "12345678901234567890123456789012"
EndIf
If Len(sInitVector) < 16
sInitVector + "1234567890123456"
EndIf
; sText = Right("00000000" + Len(sText), 8) + sText
If Len(sText) < 16
sText + Space(16-Len(sText))
EndIf
Debug "Originaltext: '" + sText + "'"
AESEncodedLength = StringByteLength(sText, #PB_Unicode) + StringByteLength(" ", #PB_Unicode) ; Die abschliessende 0 an Ende des Stringspeichers wird damit mitkodiert
*AESEncodedString = AllocateMemory(AESEncodedLength)
Debug "AESEncodedLength: " + AESEncodedLength
If *AESEncodedString > 0
If AESEncoder(@sText, *AESEncodedString, AESEncodedLength, @sKey, 256, @sInitVector) <> 0
B64EncodedLength = AESEncodedLength * 1.5
*B64EncodedString = AllocateMemory(B64EncodedLength)
Debug "B64EncodedLength: " + B64EncodedLength
If *B64EncodedString > 0
B64EncodedLength = Base64Encoder(*AESEncodedString, AESEncodedLength, *B64EncodedString, B64EncodedLength)
Debug "Real B64EncodedLength: " + B64EncodedLength
If B64EncodedLength > 0
Debug "Base64 Encoded: '" + PeekS(*B64EncodedString, B64EncodedLength, #PB_Ascii)+"'"
B64DecodedLength = B64EncodedLength * 0.75
*B64DecodedString = AllocateMemory(B64DecodedLength)
If *B64DecodedString > 0
B64DecodedLength = Base64Decoder(*B64EncodedString, B64EncodedLength, *B64DecodedString, B64DecodedLength)
If B64DecodedLength > 0
AESDecodedLength = B64DecodedLength
*AESDecodedString = AllocateMemory(AESDecodedLength)
If *AESDecodedString > 0
If AESDecoder(*B64DecodedString, *AESDecodedString, AESDecodedLength, @sKey, 256, @sInitVector) <> 0
Debug "AESDecoded Unicode ohne Länge: '"+PeekS(*AESDecodedString, #PB_Unicode)+"'"
Debug "AESDecoded Unicode mit Länge : '"+PeekS(*AESDecodedString, AESDecodedLength, #PB_Unicode)+"'"
Debug "AESDecoded Ascii ohne Länge : '"+PeekS(*AESDecodedString, #PB_Ascii)+"'"
Debug "AESDecoded Ascii mit Länge : '"+PeekS(*AESDecodedString, AESDecodedLength, #PB_Ascii)+"'"
Debug "AESDecoded Nix ohne Länge : '"+PeekS(*AESDecodedString)+"'"
Debug "AESDecoded Nix mit Länge : '"+PeekS(*AESDecodedString, AESDecodedLength)+"'"
Else
Debug "Fehler bei AESDecoder."
EndIf
Else
Debug "Speicher für *AESDecodedString konnte nicht alloziert werden."
EndIf
Else
Debug "Fehler bei Base64Decoder."
EndIf
Else
Debug "Speicher für *B64DecodedString konnte nicht alloziert werden."
EndIf
Else
Debug "Fehler bei Base64Encoder."
EndIf
Else
Debug "Speicher für *B64EncodedString konnte nicht alloziert werden."
EndIf
Else
Debug "Fehler bei AESEncoder."
EndIf
Else
Debug "Speicher für *AESEncodedString konnte nicht alloziert werden."
EndIf
If *B64DecodedString <> 0
FreeMemory(*B64DecodedString)
EndIf
If *B64EncodedString <> 0
FreeMemory(*B64EncodedString)
EndIf
If *AESDecodedString <> 0
FreeMemory(*AESDecodedString)
EndIf
If *AESEncodedString <> 0
FreeMemory(*AESEncodedString)
EndIf
ProcedureReturn sText
EndProcedure
;-
Encode("", "", "Dieser Text dienst nur einem Zweck, dem Demonstrationszweck.")


