torture the compiler ;-)
Posted: Wed Nov 28, 2018 12:57 pm
Guys,
Of course i'm not going to use the PgCrypt() func below in any production app. The only goal is to torture the compiler.. The code is based on a crypt routine from the Intl. VO Forum. To make the code even more unreadable i have replaced Substr() with _nGet () and the result string is build with _nPut (). The function compiles with VO and X# ( 2.0.0.7 ) - and even the results are the same.
To compile the func you need the 2.0.0.7 compiler
- add references to the X# Runtime dlls
- Dialect is VO
- target is x86 !
- no specific compiler switches are required.- all settings are unchecked.
The capabilities of the x# compiler are incredible !
regards
Karl-Heinz
Of course i'm not going to use the PgCrypt() func below in any production app. The only goal is to torture the compiler.. The code is based on a crypt routine from the Intl. VO Forum. To make the code even more unreadable i have replaced Substr() with _nGet () and the result string is build with _nPut (). The function compiles with VO and X# ( 2.0.0.7 ) - and even the results are the same.
To compile the func you need the 2.0.0.7 compiler
- add references to the X# Runtime dlls
- Dialect is VO
- target is x86 !
- no specific compiler switches are required.- all settings are unchecked.
The capabilities of the x# compiler are incredible !
regards
Karl-Heinz
Code: Select all
FUNCTION Start( ) AS VOID
LOCAL cValue AS STRING
cValue := PgCrypt( "The quick brown fox jumps over the lazy dog." , "CAT" )
Console.WriteLine( cValue)
cValue := PgCrypt( cValue , "CAT" )
Console.WriteLine( cValue)
RETURN
FUNCTION PgCrypt( cString AS STRING , cKey AS STRING ) AS STRING
LOCAL dwKLen, dwSLen AS DWORD
LOCAL wCode1, wCode2, wRotate, wCounter, wTemp1 , wTemp2 AS WORD
LOCAL c , c1 , c2, bnibble AS BYTE
LOCAL i,j,k AS DWORD
LOCAL cResult AS STRING
LOCAL pszKey,pszString AS PSZ
LOCAL ptrResult AS PTR
dwSLen := SLen( cString )
dwKLen := SLen( cKey )
IF dwSLen < 2 .AND. dwKLen < 2
RETURN cString
ENDIF
pszString := StringAlloc ( cString )
pszKey := StringAlloc ( cKey )
ptrResult := MemAlloc ( dwSLen )
wCode1 := WORD ( _CAST , _XOR( DWORD ( PTR( _CAST , pszKey ) ) , PszLen(pszKey) ) )
wCode2 := 0xAAAA
j := 1
FOR i := 1 TO dwSLen
IF j > dwKLen
j := 1
ENDIF
c1 := BYTE ( _CAST , _NGet ( pszString , i- 1 ) )
c2 := BYTE ( _CAST , _NGet ( pszKey , j - 1 ) )
c := BYTE ( _CAST , _XOR( WORD( _CAST , c1 ) , WORD ( _CAST , c2 ) ) )
wCode1 := _XOR( wCode1 , wCode1 >> 8 )
wRotate := _AND( wCode1 , 0xF )
wTemp1 := wCode1
FOR k := 1 TO wRotate
wTemp1 := wTemp1 >> 1
NEXT
wTemp2 := wCode1
FOR k := 1 TO 16-wRotate
wTemp2 := wTemp2 << 1
NEXT
wCode1 := _OR( wTemp1 , wTemp2 )
wCode1 := _XOR( wCode1 , wCode2 )
wCode1 := wCode1 + 0x10
wCounter := _AND( wCode1 , 0x1E )
wCounter ++
wCounter ++
DO WHILE wCounter > 0
wCounter --
wRotate := _AND( wCounter , 0xF )
wTemp1 := wCode2
FOR k := 1 TO wRotate
wTemp1 := wTemp1 >> 1
NEXT
wTemp2 := wCode2
FOR k := 1 TO 16 - wRotate
wTemp2 := wTemp2 << 1
NEXT
wCode2 := _OR( wTemp1 , wTemp2 )
wCode2 := _OR( wCode2 << 8 , _XOR( ( wCode2 >> 8 ) , 0xFF ) )
wCode2 := _OR( wCode2 << 1 , wCode2 >> 15 )
wCode2 := _XOR( wCode2 , 0xAAAA )
bnibble := BYTE ( _CAST , _AND( wCode2 , 0xFF ) )
wTemp1 := bnibble << 1
IF wTemp1 > 255
wTemp1 := wTemp1 - 255
ENDIF
wTemp2 := bnibble >> 7
bnibble := BYTE ( _CAST , _OR( wTemp1 , wTemp2 ) )
wCode2 := _OR( _AND( wCode2 , 0xFF00 ) , bnibble )
wCounter --
ENDDO
j ++
_NPut ( ptrResult , i - 1 , BYTE ( _CAST , _XOR( WORD ( _CAST , c ) , WORD ( _CAST , bnibble ) ) ) )
NEXT
cResult := Mem2String ( ptrResult , dwSLen )
// ? SLen ( cString )
// ? SLen ( cResult)
MemFree ( pszString )
MemFree ( pszKey )
MemFree ( ptrResult)
RETURN cResult