Jump to content

Recommended Posts

Posted

UDF:

#include-once
#cs ----------------------------------------------------------------------------
    ; LZNT1 Compression
    ; AutoIt Version: 3.3.16.1+
    ; Description:    Supports compression and decompression of binary data and strings using the Windows LZNT1 algorithm.
    ; Author:         trancexx + rewritten & extended by Dao Van Trong - TRONG.PRO
    ;
    ; Functions:
    ;   _LZNT_Compress($bInput, $iEngine = 2, $bBase64 = False, $iLineLen = 1024)
    ;   _LZNT_Decompress($vInput, $iOrigSize = 0, $iEngine = 2, $bBase64 = False)
    ;   _LZNT_CompressString($sInput, $iEncoding = 4, $iEngine = 2, $bBase64 = False, $iLineLen = 1024)
    ;   _LZNT_DecompressString($vInput, $iOrigSize = 0, $iEncoding = 4, $iEngine = 2, $bBase64 = False)
    ;
#ce ----------------------------------------------------------------------------

; ===============================================================================================================================
; Public Function: Compress Binary
; ===============================================================================================================================
; Description: Compresses binary data using the LZNT1 algorithm.
; Parameters:
;   $bInput     - Binary data to be compressed.
;   $iEngine    - Compression engine.
;                 2 (default) = COMPRESSION_FORMAT_LZNT1 | $COMPRESSION_ENGINE_STANDARD
;                 258         = COMPRESSION_ENGINE_MAXIMUM
;   $bBase64    - True to return a Base64 string, False to return binary data.
;   $iLineLen   - Line length when returning a Base64 string (default is 1024 characters).
; Return Value: Returns the compressed data (binary or Base64).
; On Failure:   Returns an empty string (""), @error is set to:
;               1 = Error calling RtlGetCompressionWorkSpaceSize.
;               2 = Error calling RtlCompressBuffer.
;               3 = Error converting to Base64 in __Base64Encode.
;               @extended is set to the original length of the binary data.
; Author:       Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _LZNT_Compress($bInput, $iEngine = 2, $bBase64 = False, $iLineLen = 1024)
    If Not IsBinary($bInput) Then $bInput = Binary($bInput)
    If $iEngine <> 2 And $iEngine <> 258 Then $iEngine = 2
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]")
    DllStructSetData($tInput, 1, $bInput)
    Local $aCall = DllCall("ntdll.dll", "int", "RtlGetCompressionWorkSpaceSize", _
            "ushort", $iEngine, "dword*", 0, "dword*", 0)
    If @error Or $aCall[0] Then Return SetError(1, 0, "")
    Local $tWork = DllStructCreate("byte[" & $aCall[2] & "]")
    Local $tBuffer = DllStructCreate("byte[" & 16 * DllStructGetSize($tInput) & "]")
    $aCall = DllCall("ntdll.dll", "int", "RtlCompressBuffer", _
            "ushort", $iEngine, _
            "ptr", DllStructGetPtr($tInput), "dword", DllStructGetSize($tInput), _
            "ptr", DllStructGetPtr($tBuffer), "dword", DllStructGetSize($tBuffer), _
            "dword", 4096, "dword*", 0, "ptr", DllStructGetPtr($tWork))
    If @error Or $aCall[0] Then Return SetError(2, 0, "")
    Local $tOut = DllStructCreate("byte[" & $aCall[7] & "]", DllStructGetPtr($tBuffer))
    Local $bOut = DllStructGetData($tOut, 1)
    If $bBase64 Then Return SetError(0, DllStructGetSize($tInput), __Base64Encode($bOut, $iLineLen))
    Return SetError(0, DllStructGetSize($tInput), $bOut)
EndFunc   ;==>_LZNT_Compress

; ===============================================================================================================================
; Public Function: Decompress Binary
; ===============================================================================================================================
; Description: Decompresses LZNT1-compressed binary data.
; Parameters:
;   $vInput     - Compressed data, can be binary or a Base64 string.
;   $iOrigSize  - Estimated original size of the uncompressed data. If < 1, it will be estimated automatically.
;   $iEngine    - Compression engine used.
;                 2 (default) = COMPRESSION_FORMAT_LZNT1 | $COMPRESSION_ENGINE_STANDARD
;                 258         = COMPRESSION_ENGINE_MAXIMUM
;   $bBase64    - True if $vInput is a Base64 string, False if it is binary data.
; Return Value: Returns the decompressed binary data.
; On Failure:   Returns an empty string (""), @error is set to:
;               1 = Decompression error, or $vInput is not Base64 when $bBase64 is True.
;               @extended is set to 0.
; Author:       Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _LZNT_Decompress($vInput, $iOrigSize = 0, $iEngine = 2, $bBase64 = False)
    Local $bInput
    If $bBase64 Then
        $bInput = __Base64Decode($vInput)
    Else
        $bInput = $vInput
    EndIf
    If Not IsBinary($bInput) Then $bInput = Binary($bInput)
    If $iEngine <> 2 And $iEngine <> 258 Then $iEngine = 2
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]")
    DllStructSetData($tInput, 1, $bInput)
    If $iOrigSize < 1 Then $iOrigSize = 16 * DllStructGetSize($tInput)
    Local $tBuffer = DllStructCreate("byte[" & $iOrigSize & "]")
    Local $aCall = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", _
            "ushort", $iEngine, _
            "ptr", DllStructGetPtr($tBuffer), "dword", DllStructGetSize($tBuffer), _
            "ptr", DllStructGetPtr($tInput), "dword", DllStructGetSize($tInput), _
            "dword*", 0)
    If @error Or $aCall[0] Then Return SetError(1, 0, "")
    Local $tOut = DllStructCreate("byte[" & $aCall[6] & "]", DllStructGetPtr($tBuffer))
    Return SetError(0, $aCall[6], DllStructGetData($tOut, 1))
EndFunc   ;==>_LZNT_Decompress

; ===============================================================================================================================
; Public Function: Compress String
; ===============================================================================================================================
; Description: Compresses a string and returns the compressed data.
; Parameters:
;   $sInput     - String to be compressed.
;   $iEncoding  - String encoding. (1=ANSI, 2=UTF16LE, 3=UTF16BE, 4=UTF8)
;   $iEngine    - Compression engine (same as _LZNT_Compress).(2 or 258)
;   $bBase64    - True to return a Base64 string, False to return binary.
;   $iLineLen   - Line length when returning a Base64 string.
; Return Value: Returns the compressed data (binary or Base64).
; On Failure:   Returns an empty string (""), @error is set to:
;               1, 2, 3 (same as _LZNT_Compress).
;               @extended is set to the original length of the string data.
; Author:       Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _LZNT_CompressString($sInput, $iEncoding = 4, $iEngine = 2, $bBase64 = False, $iLineLen = 1024)
    Local $bData = StringToBinary($sInput, $iEncoding)
    Return _LZNT_Compress($bData, $iEngine, $bBase64, $iLineLen)
EndFunc   ;==>_LZNT_CompressString

; ===============================================================================================================================
; Public Function: Decompress String
; ===============================================================================================================================
; Description: Decompresses data and returns a string.
; Parameters:
;   $vInput     - Compressed data.
;   $iOrigSize  - Estimated original size of the uncompressed data.
;   $iEncoding  - Encoding to convert the decompressed binary to a string. (1=ANSI, 2=UTF16LE, 3=UTF16BE, 4=UTF8)
;   $iEngine    - Compression engine used (same as _LZNT_Decompress).(2 or 258)
;   $bBase64    - True if $vInput is a Base64 string, False if it is binary.
; Return Value: Returns the decompressed string.
; On Failure:   Returns an empty string (""), @error is set to:
;               1 = Decompression error (same as _LZNT_Decompress).
;               @extended is set to 0.
; Author:       Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _LZNT_DecompressString($vInput, $iOrigSize = 0, $iEncoding = 4, $iEngine = 2, $bBase64 = False)
    Local $bData = _LZNT_Decompress($vInput, $iOrigSize, $iEngine, $bBase64)
    If @error Then Return SetError(1, 0, "")
    Return BinaryToString($bData, $iEncoding)
EndFunc   ;==>_LZNT_DecompressString

; ===============================================================================================================================
; Internal helper: Base64 Encode
; ===============================================================================================================================
Func __Base64Encode($bData, $iLineLen = 1024)
    If Not IsBinary($bData) Then Return SetError(1, 0, "")
    Local $pInput = DllStructCreate("byte[" & BinaryLen($bData) & "]")
    DllStructSetData($pInput, 1, $bData)
    ; 1st call to get required length
    Local $aCall = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _
            "ptr", DllStructGetPtr($pInput), _
            "dword", DllStructGetSize($pInput), _
            "dword", 0x1, _ ; CRYPT_STRING_BASE64
            "ptr", 0, _
            "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(2, 0, "")
    Local $iLen = $aCall[5]
    Local $tOut = DllStructCreate("wchar[" & $iLen & "]")
    ; 2nd call to actually encode
    $aCall = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _
            "ptr", DllStructGetPtr($pInput), _
            "dword", DllStructGetSize($pInput), _
            "dword", 0x1, _
            "ptr", DllStructGetPtr($tOut), _
            "dword*", $iLen)
    If @error Or Not $aCall[0] Then Return SetError(3, 0, "")
    Local $sOut = DllStructGetData($tOut, 1)
    ; Remove CRLF inserted by Crypt32
    $sOut = StringReplace($sOut, @CRLF, "")
    ; Manual wrap for embedding in AutoIt source
    If $iLineLen > 0 And StringLen($sOut) > $iLineLen Then
        Local $sWrapped = ""
        For $i = 1 To StringLen($sOut) Step $iLineLen
            $sWrapped &= StringMid($sOut, $i, $iLineLen) & @CRLF
        Next
        $sOut = StringTrimRight($sWrapped, 2)
    EndIf
    Return $sOut
EndFunc   ;==>__Base64Encode

; ===============================================================================================================================
; Internal helper: Base64 Decode
; ===============================================================================================================================
Func __Base64Decode($sBase64)
    If Not IsString($sBase64) Then Return SetError(1, 0, "")
    ; strip whitespace / CRLF
    $sBase64 = StringStripWS($sBase64, 8)
    ; 1st call to get required length
    Local $aCall = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _
            "wstr", $sBase64, _
            "dword", 0, _
            "dword", 0x1, _ ; CRYPT_STRING_BASE64
            "ptr", 0, _
            "dword*", 0, _
            "dword*", 0, _
            "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(2, 0, "")
    Local $iLen = $aCall[5]
    Local $tOut = DllStructCreate("byte[" & $iLen & "]")
    ; 2nd call to decode
    $aCall = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _
            "wstr", $sBase64, _
            "dword", 0, _
            "dword", 0x1, _
            "ptr", DllStructGetPtr($tOut), _
            "dword*", $iLen, _
            "dword*", 0, _
            "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(3, 0, "")
    Return DllStructGetData($tOut, 1)
EndFunc   ;==>__Base64Decode



#cs
; ===============================================================================================================================
; SELF-TEST FOR LZNT + BASE64 UDF
; ===============================================================================================================================

; Test string with 10 languages
Global Const $sTest = "Hello 你好  नमस्ते Hola Bonjour مرحبا হ্যালো Привет Olá Xin chào 🚀"

ConsoleWrite("!===== SELF TEST START =====" & @CRLF)
ConsoleWrite("+ Original String: " & $sTest & @CRLF)
ConsoleWrite("- Original Length: " & StringLen($sTest) & " chars" & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 1) Compress binary
; -------------------------------------------------------------------------------------------------------------------------------
Local $bInput = StringToBinary($sTest, 4)     ; UTF-8
Local $bCompressed = _LZNT_Compress($bInput, 2, False)
Local $iOrigSize = @extended
ConsoleWrite(@CRLF & "- [1] Compress Binary (HEX)" & @CRLF)
ConsoleWrite("+ OrigSize: " & $iOrigSize & " CompressedSize: " & BinaryLen($bCompressed) & @CRLF)

; Decompress binary
Local $bDecompressed = _LZNT_Decompress($bCompressed, $iOrigSize, 2, False)
ConsoleWrite("" & (BinaryToString($bDecompressed, 4) = $sTest ? '- Decompressed OK' : '! Decompressed NG') & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 2) Compress binary + Base64
; -------------------------------------------------------------------------------------------------------------------------------
Local $sCompressedB64 = _LZNT_Compress($bInput, 2, True, 32)
$iOrigSize = @extended
ConsoleWrite(@CRLF & "- [2] Compress Binary (Base64)" & @CRLF)
ConsoleWrite("+ Compressed (B64): " & @CRLF & $sCompressedB64 & @CRLF)

; Decompress binary from Base64
$bDecompressed = _LZNT_Decompress($sCompressedB64, $iOrigSize, 2, True)
ConsoleWrite("" & (BinaryToString($bDecompressed, 4) = $sTest ? '- Decompressed  OK' : '! Decompressed  NG') & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 3) Compress String (HEX)
; -------------------------------------------------------------------------------------------------------------------------------
Local $sCompressedStr = _LZNT_CompressString($sTest, 4, 2, False)
$iOrigSize = @extended
ConsoleWrite(@CRLF & "- [3] Compress String (HEX)" & @CRLF)
ConsoleWrite("+ CompressedSize: " & BinaryLen($sCompressedStr) & @CRLF)

; Decompress String
Local $sDecompressed = _LZNT_DecompressString($sCompressedStr, $iOrigSize, 4, 2, False)
ConsoleWrite("- Decompressed String: " & $sDecompressed & @CRLF)
ConsoleWrite("" & ($sDecompressed = $sTest ? '- Decompressed  OK' : '! Decompressed  NG') & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 4) Compress String (Base64)
; -------------------------------------------------------------------------------------------------------------------------------
Local $sCompressedStrB64 = _LZNT_CompressString($sTest, 4, 2, True, 40)
$iOrigSize = @extended
ConsoleWrite(@CRLF & "- [4] Compress String (Base64)" & @CRLF)
ConsoleWrite("+ Compressed (B64): " & @CRLF & $sCompressedStrB64 & @CRLF)

; Decompress String
$sDecompressed = _LZNT_DecompressString($sCompressedStrB64, $iOrigSize, 4, 2, True)
ConsoleWrite("- Decompressed String: " & $sDecompressed & @CRLF)
ConsoleWrite("" & ($sDecompressed = $sTest ? '- Decompressed  OK' : '! Decompressed  NG') & @CRLF)

ConsoleWrite("!===== SELF TEST END =====" & @CRLF)

#ce

EG:

;#include "LZNT_Compress_Engine.AU3"
; ===============================================================================================================================
; SELF-TEST FOR LZNT + BASE64 UDF
; ===============================================================================================================================

; Test string with 10 languages
Global Const $sTest = "Hello 你好  नमस्ते Hola Bonjour مرحبا হ্যালো Привет Olá Xin chào 🚀"

ConsoleWrite("!===== SELF TEST START =====" & @CRLF)
ConsoleWrite("+ Original String: " & $sTest & @CRLF)
ConsoleWrite("- Original Length: " & StringLen($sTest) & " chars" & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 1) Compress binary
; -------------------------------------------------------------------------------------------------------------------------------
Local $bInput = StringToBinary($sTest, 4)     ; UTF-8
Local $bCompressed = _LZNT_Compress($bInput, 2, False)
Local $iOrigSize = @extended
ConsoleWrite(@CRLF & "- [1] Compress Binary (HEX)" & @CRLF)
ConsoleWrite("+ OrigSize: " & $iOrigSize & " CompressedSize: " & BinaryLen($bCompressed) & @CRLF)

; Decompress binary
Local $bDecompressed = _LZNT_Decompress($bCompressed, $iOrigSize, 2, False)
ConsoleWrite("" & (BinaryToString($bDecompressed, 4) = $sTest ? '- Decompressed OK' : '! Decompressed NG') & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 2) Compress binary + Base64
; -------------------------------------------------------------------------------------------------------------------------------
Local $sCompressedB64 = _LZNT_Compress($bInput, 2, True, 32)
$iOrigSize = @extended
ConsoleWrite(@CRLF & "- [2] Compress Binary (Base64)" & @CRLF)
ConsoleWrite("+ Compressed (B64): " & @CRLF & $sCompressedB64 & @CRLF)

; Decompress binary from Base64
$bDecompressed = _LZNT_Decompress($sCompressedB64, $iOrigSize, 2, True)
ConsoleWrite("" & (BinaryToString($bDecompressed, 4) = $sTest ? '- Decompressed  OK' : '! Decompressed  NG') & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 3) Compress String (HEX)
; -------------------------------------------------------------------------------------------------------------------------------
Local $sCompressedStr = _LZNT_CompressString($sTest, 4, 2, False)
$iOrigSize = @extended
ConsoleWrite(@CRLF & "- [3] Compress String (HEX)" & @CRLF)
ConsoleWrite("+ CompressedSize: " & BinaryLen($sCompressedStr) & @CRLF)

; Decompress String
Local $sDecompressed = _LZNT_DecompressString($sCompressedStr, $iOrigSize, 4, 2, False)
ConsoleWrite("- Decompressed String: " & $sDecompressed & @CRLF)
ConsoleWrite("" & ($sDecompressed = $sTest ? '- Decompressed  OK' : '! Decompressed  NG') & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 4) Compress String (Base64)
; -------------------------------------------------------------------------------------------------------------------------------
Local $sCompressedStrB64 = _LZNT_CompressString($sTest, 4, 2, True, 40)
$iOrigSize = @extended
ConsoleWrite(@CRLF & "- [4] Compress String (Base64)" & @CRLF)
ConsoleWrite("+ Compressed (B64): " & @CRLF & $sCompressedStrB64 & @CRLF)

; Decompress String
$sDecompressed = _LZNT_DecompressString($sCompressedStrB64, $iOrigSize, 4, 2, True)
ConsoleWrite("- Decompressed String: " & $sDecompressed & @CRLF)
ConsoleWrite("" & ($sDecompressed = $sTest ? '- Decompressed  OK' : '! Decompressed  NG') & @CRLF)

ConsoleWrite("!===== SELF TEST END =====" & @CRLF)

#ce

!

Regards,
 

Posted

v2:

#include-once
#cs ----------------------------------------------------------------------------
    ; LZNT1 Compression
    ; AutoIt Version: 3.3.16.1+
    ; Description:    Supports compression and decompression of binary data and strings using the Windows LZNT1 algorithm.
    ; Author:         trancexx + rewritten & extended by Dao Van Trong - TRONG.PRO
    ;
    ; Functions:
    ;   _LZNT_Compress($bInput, $iEngine = 2, $bBase64 = False, $iLineLen = 1024)
    ;   _LZNT_Decompress($vInput, $iOrigSize = 0, $iEngine = 2, $bBase64 = False)
    ;   _LZNT_CompressString($sInput, $iEncoding = 4, $iEngine = 2, $bBase64 = False, $iLineLen = 1024)
    ;   _LZNT_DecompressString($vInput, $iOrigSize = 0, $iEncoding = 4, $iEngine = 2, $bBase64 = False)
    ;
#ce ----------------------------------------------------------------------------

; ===============================================================================================================================
; Public Function: Compress Binary
; ===============================================================================================================================
; Description: Compresses binary data using the LZNT1 algorithm.
; Parameters:
;   $bInput     - Binary data to be compressed.
;   $iEngine    - Compression engine.
;                 2             = COMPRESSION_FORMAT_LZNT1 | $COMPRESSION_ENGINE_STANDARD
;                 258 (default) = COMPRESSION_ENGINE_MAXIMUM
;   $bBase64    - True to return a Base64 string, False to return binary data.
;   $iLineLen   - Line length when returning a Base64 string (default is 1024 characters).
; Return Value: Returns the compressed data (binary or Base64).
; On Failure:   Returns an empty string (""), @error is set to:
;               1 = Error calling RtlGetCompressionWorkSpaceSize.
;               2 = Error calling RtlCompressBuffer.
;               3 = Error converting to Base64 in __Base64Encode.
;               @extended is set to the original length of the binary data.
; Author:       Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _LZNT_Compress($bInput, $iOrigSize = 2, $iEngine = 258, $bBase64 = False, $iLineLen = 1024)
    If Not IsBinary($bInput) Then $bInput = Binary($bInput)
    If $iEngine <> 2 And $iEngine <> 258 Then $iEngine = 258
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]")
    DllStructSetData($tInput, 1, $bInput)
    Local $aCall = DllCall("ntdll.dll", "int", "RtlGetCompressionWorkSpaceSize", _
            "ushort", $iEngine, "dword*", 0, "dword*", 0)
    If @error Or $aCall[0] Then Return SetError(1, 0, "")
    Local $tWork = DllStructCreate("byte[" & $aCall[2] & "]")
    If $iOrigSize < 1 Then $iOrigSize = 16
    Local $iLen = $iOrigSize * DllStructGetSize($tInput)
    Local $tBuffer = DllStructCreate("byte[" & $iLen & "]")
    $aCall = DllCall("ntdll.dll", "int", "RtlCompressBuffer", _
            "ushort", $iEngine, _
            "ptr", DllStructGetPtr($tInput), "dword", DllStructGetSize($tInput), _
            "ptr", DllStructGetPtr($tBuffer), "dword", DllStructGetSize($tBuffer), _
            "dword", 4096, "dword*", 0, "ptr", DllStructGetPtr($tWork))
    If @error Or $aCall[0] Then Return SetError(2, 0, "")
    Local $tOut = DllStructCreate("byte[" & $aCall[7] & "]", DllStructGetPtr($tBuffer))
    Local $bOut = DllStructGetData($tOut, 1)
    If $bBase64 Then Return SetError(0, DllStructGetSize($tInput), __Base64Encode($bOut, $iLineLen))
    Return SetError(0, DllStructGetSize($tInput), $bOut)
EndFunc   ;==>_LZNT_Compress

; ===============================================================================================================================
; Public Function: Decompress Binary
; ===============================================================================================================================
; Description: Decompresses LZNT1-compressed binary data.
; Parameters:
;   $vInput     - Compressed data, can be binary or a Base64 string.
;   $iOrigSize  - Estimated original size of the uncompressed data. If < 1, it will be estimated automatically.
;   $iEngine    - Compression engine used.
;                 2             = COMPRESSION_FORMAT_LZNT1 | $COMPRESSION_ENGINE_STANDARD
;                 258 (default) = COMPRESSION_ENGINE_MAXIMUM
;   $bBase64    - True if $vInput is a Base64 string, False if it is binary data.
; Return Value: Returns the decompressed binary data.
; On Failure:   Returns an empty string (""), @error is set to:
;               1 = Decompression error, or $vInput is not Base64 when $bBase64 is True.
;               @extended is set to 0.
; Author:       Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _LZNT_Decompress($vInput, $iOrigSize = 2, $iEngine = 258, $bBase64 = False)
    Local $bInput
    If $bBase64 Then
        $bInput = __Base64Decode($vInput)
    Else
        $bInput = $vInput
    EndIf
    If Not IsBinary($bInput) Then $bInput = Binary($bInput)
    If $iEngine <> 2 And $iEngine <> 258 Then $iEngine = 258
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]")
    DllStructSetData($tInput, 1, $bInput)
    If $iOrigSize < 1 Then $iOrigSize = 16
    Local $iLen = $iOrigSize * DllStructGetSize($tInput)
    Local $tBuffer = DllStructCreate("byte[" & $iLen & "]")
    Local $aCall = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", _
            "ushort", $iEngine, _
            "ptr", DllStructGetPtr($tBuffer), "dword", DllStructGetSize($tBuffer), _
            "ptr", DllStructGetPtr($tInput), "dword", DllStructGetSize($tInput), _
            "dword*", 0)
    If @error Or $aCall[0] Then Return SetError(1, 0, "")
    Local $tOut = DllStructCreate("byte[" & $aCall[6] & "]", DllStructGetPtr($tBuffer))
    Return SetError(0, $aCall[6], DllStructGetData($tOut, 1))
EndFunc   ;==>_LZNT_Decompress

; ===============================================================================================================================
; Public Function: Compress String
; ===============================================================================================================================
; Description: Compresses a string and returns the compressed data.
; Parameters:
;   $sInput     - String to be compressed.
;   $iEncoding  - String encoding. (1=ANSI, 2=UTF16LE, 3=UTF16BE, 4=UTF8)
;   $iEngine    - Compression engine (same as _LZNT_Compress).(2 or 258)
;   $bBase64    - True to return a Base64 string, False to return binary.
;   $iLineLen   - Line length when returning a Base64 string.
; Return Value: Returns the compressed data (binary or Base64).
; On Failure:   Returns an empty string (""), @error is set to:
;               1, 2, 3 (same as _LZNT_Compress).
;               @extended is set to the original length of the string data.
; Author:       Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _LZNT_CompressString($sInput, $iOrigSize = 0, $iEncoding = 4, $iEngine = 2, $bBase64 = False, $iLineLen = 1024)
    Local $bData = StringToBinary($sInput, $iEncoding)
    Return _LZNT_Compress($bData, $iOrigSize, $iEngine, $bBase64, $iLineLen)
EndFunc   ;==>_LZNT_CompressString

; ===============================================================================================================================
; Public Function: Decompress String
; ===============================================================================================================================
; Description: Decompresses data and returns a string.
; Parameters:
;   $vInput     - Compressed data.
;   $iOrigSize  - Estimated original size of the uncompressed data.
;   $iEncoding  - Encoding to convert the decompressed binary to a string. (1=ANSI, 2=UTF16LE, 3=UTF16BE, 4=UTF8)
;   $iEngine    - Compression engine used (same as _LZNT_Decompress).(2 or 258)
;   $bBase64    - True if $vInput is a Base64 string, False if it is binary.
; Return Value: Returns the decompressed string.
; On Failure:   Returns an empty string (""), @error is set to:
;               1 = Decompression error (same as _LZNT_Decompress).
;               @extended is set to 0.
; Author:       Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _LZNT_DecompressString($vInput, $iOrigSize = 0, $iEncoding = 4, $iEngine = 2, $bBase64 = False)
    Local $bData = _LZNT_Decompress($vInput, $iOrigSize, $iEngine, $bBase64)
    If @error Then Return SetError(1, 0, "")
    Return BinaryToString($bData, $iEncoding)
EndFunc   ;==>_LZNT_DecompressString

; ===============================================================================================================================
; Internal helper: Base64 Encode
; ===============================================================================================================================
Func __Base64Encode($bData, $iLineLen = 1024)
    If Not IsBinary($bData) Then Return SetError(1, 0, "")
    Local $pInput = DllStructCreate("byte[" & BinaryLen($bData) & "]")
    DllStructSetData($pInput, 1, $bData)
    ; 1st call to get required length
    Local $aCall = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _
            "ptr", DllStructGetPtr($pInput), _
            "dword", DllStructGetSize($pInput), _
            "dword", 0x1, _ ; CRYPT_STRING_BASE64
            "ptr", 0, _
            "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(2, 0, "")
    Local $iLen = $aCall[5]
    Local $tOut = DllStructCreate("wchar[" & $iLen & "]")
    ; 2nd call to actually encode
    $aCall = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _
            "ptr", DllStructGetPtr($pInput), _
            "dword", DllStructGetSize($pInput), _
            "dword", 0x1, _
            "ptr", DllStructGetPtr($tOut), _
            "dword*", $iLen)
    If @error Or Not $aCall[0] Then Return SetError(3, 0, "")
    Local $sOut = DllStructGetData($tOut, 1)
    ; Remove CRLF inserted by Crypt32
    $sOut = StringReplace($sOut, @CRLF, "")
    ; Manual wrap for embedding in AutoIt source
    If $iLineLen > 0 And StringLen($sOut) > $iLineLen Then
        Local $sWrapped = ""
        For $i = 1 To StringLen($sOut) Step $iLineLen
            $sWrapped &= StringMid($sOut, $i, $iLineLen) & @CRLF
        Next
        $sOut = StringTrimRight($sWrapped, 2)
    EndIf
    Return $sOut
EndFunc   ;==>__Base64Encode

; ===============================================================================================================================
; Internal helper: Base64 Decode
; ===============================================================================================================================
Func __Base64Decode($sBase64)
    If Not IsString($sBase64) Then Return SetError(1, 0, "")
    ; strip whitespace / CRLF
    $sBase64 = StringStripWS($sBase64, 8)
    ; 1st call to get required length
    Local $aCall = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _
            "wstr", $sBase64, _
            "dword", 0, _
            "dword", 0x1, _ ; CRYPT_STRING_BASE64
            "ptr", 0, _
            "dword*", 0, _
            "dword*", 0, _
            "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(2, 0, "")
    Local $iLen = $aCall[5]
    Local $tOut = DllStructCreate("byte[" & $iLen & "]")
    ; 2nd call to decode
    $aCall = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _
            "wstr", $sBase64, _
            "dword", 0, _
            "dword", 0x1, _
            "ptr", DllStructGetPtr($tOut), _
            "dword*", $iLen, _
            "dword*", 0, _
            "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(3, 0, "")
    Return DllStructGetData($tOut, 1)
EndFunc   ;==>__Base64Decode



;#cs
; ===============================================================================================================================
; SELF-TEST FOR LZNT + BASE64 UDF
; ===============================================================================================================================

; Test string with 10 languages
Global Const $sTest = "Hello 你好  नमस्ते Hola Bonjour مرحبا হ্যালো Привет Olá Xin chào 🚀"

ConsoleWrite("!===== SELF TEST START =====" & @CRLF)
ConsoleWrite("+ Original String: " & $sTest & @CRLF)
ConsoleWrite("- Original Length: " & StringLen($sTest) & " chars" & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 1) Compress binary
; -------------------------------------------------------------------------------------------------------------------------------
Local $bInput = StringToBinary($sTest, 4)     ; UTF-8
Local $bCompressed = _LZNT_Compress($bInput, 2, 2, False)
Local $iOrigSize = @extended
ConsoleWrite(@CRLF & "- [1] Compress Binary (HEX)" & @CRLF)
ConsoleWrite("+ OrigSize: " & $iOrigSize & " CompressedSize: " & BinaryLen($bCompressed) & @CRLF)

; Decompress binary
Local $bDecompressed = _LZNT_Decompress($bCompressed, $iOrigSize, 2, False)
ConsoleWrite("" & (BinaryToString($bDecompressed, 4) = $sTest ? '+ Decompressed OK' : '! Decompressed NG') & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 2) Compress binary + Base64
; -------------------------------------------------------------------------------------------------------------------------------
Local $sCompressedB64 = _LZNT_Compress($bInput, 2, 2, True, 32)
$iOrigSize = @extended
ConsoleWrite(@CRLF & "- [2] Compress Binary (Base64)" & @CRLF)
ConsoleWrite("> Compressed (B64): " & @CRLF & $sCompressedB64 & @CRLF)

; Decompress binary from Base64
$bDecompressed = _LZNT_Decompress($sCompressedB64, $iOrigSize, 2, True)
ConsoleWrite("" & (BinaryToString($bDecompressed, 4) = $sTest ? '+ Decompressed  OK' : '! Decompressed  NG') & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 3) Compress String (HEX)
; -------------------------------------------------------------------------------------------------------------------------------
Local $sCompressedStr = _LZNT_CompressString($sTest, 2, 4, 2, False)
$iOrigSize = @extended
ConsoleWrite(@CRLF & "- [3] Compress String (HEX)" & @CRLF)
ConsoleWrite("> CompressedSize: " & BinaryLen($sCompressedStr) & @CRLF)

; Decompress String
Local $sDecompressed = _LZNT_DecompressString($sCompressedStr, $iOrigSize, 4, 2, False)
ConsoleWrite("- Decompressed String: " & $sDecompressed & @CRLF)
ConsoleWrite("" & ($sDecompressed = $sTest ? '+ Decompressed  OK' : '! Decompressed  NG') & @CRLF)

; -------------------------------------------------------------------------------------------------------------------------------
; 4) Compress String (Base64)
; -------------------------------------------------------------------------------------------------------------------------------
Local $sCompressedStrB64 = _LZNT_CompressString($sTest, 2, 4, 2, True, 64)
$iOrigSize = @extended
ConsoleWrite(@CRLF & "- [4] Compress String (Base64)" & @CRLF)
ConsoleWrite("> Compressed (B64): " & @CRLF & $sCompressedStrB64 & @CRLF)

; Decompress String
$sDecompressed = _LZNT_DecompressString($sCompressedStrB64, $iOrigSize, 4, 2, True)
ConsoleWrite("- Decompressed String: " & $sDecompressed & @CRLF)
ConsoleWrite("" & ($sDecompressed = $sTest ? '+ Decompressed  OK' : '! Decompressed  NG') & @CRLF)

ConsoleWrite("!===== SELF TEST END =====" & @CRLF)

;#ce

!

Regards,
 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...