Jump to content

Recommended Posts

Posted

I was just searching the forum for a proper way to decode base64 encoded strings but didn't find any good function. So I created my own:

; ===================================================================
; Base64 Encode/Decode Functions for AutoIt
; by Dao Van Trong - TRONG.PRO
; ===================================================================

; ===================================================================
; Function: _Base64Encode($bInput, $bNoCRLF = True)
; Description: Encode binary data to Base64 string
; Parameters:
;   $bInput   - Binary data to encode (can also accept ASCII string directly)
;   $bNoCRLF  - True: no line breaks, False: add CRLF every 76 chars
; Return: Base64 encoded string
; Notes:
;   - For ASCII strings, you can use this function directly
;   - For UTF-8 strings, use _Base64EncodeStr() instead
; Author : Dao Van Trong - TRONG.PRO
; ===================================================================
Func _Base64Encode($bInput, $bNoCRLF = True)
    $bInput = Binary($bInput)
    Local $iFlags = 1 ; CRYPT_STRING_BASE64
    If $bNoCRLF Then $iFlags = 0x40000001 ; CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]")
    DllStructSetData($tInput, 1, $bInput)
    ; Get required buffer size
    Local $aResult = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _
        "struct*", $tInput, _
        "dword", DllStructGetSize($tInput), _
        "dword", $iFlags, _
        "ptr", 0, _
        "dword*", 0)
    If @error Or Not $aResult[0] Then Return SetError(1, 0, "")
    Local $iSize = $aResult[5]
    Local $tOutput = DllStructCreate("wchar[" & $iSize & "]")
    ; Perform encoding
    $aResult = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _
        "struct*", $tInput, _
        "dword", DllStructGetSize($tInput), _
        "dword", $iFlags, _
        "struct*", $tOutput, _
        "dword*", $iSize)
    If @error Or Not $aResult[0] Then Return SetError(2, 0, "")
    Return DllStructGetData($tOutput, 1)
EndFunc

; ===================================================================
; Function: _Base64Decode($sInput, $bReturnBinary = True, $iDecodeType = 1)
; Description: Decode Base64 string to binary or string
; Parameters:
;   $sInput        - Base64 string to decode
;   $bReturnBinary - False: return string (default), True: return binary
;   $iDecodeType   - 1: ASCII (default), 4: UTF-8 (only used when $bReturnBinary = False)
; Return: Binary data or string
; Notes:
;   - If $bReturnBinary = False (default): decodes to string using $iDecodeType (1=ASCII, 4=UTF-8)
;   - If $bReturnBinary = True: returns raw binary (works for all data types)
;   - For ASCII-only data, use default parameters
;   - For UTF-8 data, use $iDecodeType = 4
;   - For binary data, use $bReturnBinary = True
; Author : Dao Van Trong - TRONG.PRO
; ===================================================================
Func _Base64Decode($sInput, $bReturnBinary = False, $iDecodeType = 1)
    If ($iDecodeType > 4) Or ($iDecodeType < 1) Then $iDecodeType = 4
    ; Remove all whitespace and CRLF
    $sInput = StringRegExpReplace($sInput, "\s", "")
    If $sInput = "" Then Return SetError(1, 0, Binary(""))
    Local $iFlags = 1 ; CRYPT_STRING_BASE64
    ; Get required buffer size
    Local $aResult = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _
        "wstr", $sInput, _
        "dword", StringLen($sInput), _
        "dword", $iFlags, _
        "ptr", 0, _
        "dword*", 0, _
        "ptr", 0, _
        "ptr", 0)
    If @error Or Not $aResult[0] Then Return SetError(2, 0, Binary(""))
    Local $iSize = $aResult[5]
    Local $tOutput = DllStructCreate("byte[" & $iSize & "]")
    ; Perform decoding
    $aResult = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _
        "wstr", $sInput, _
        "dword", StringLen($sInput), _
        "dword", $iFlags, _
        "struct*", $tOutput, _
        "dword*", $iSize, _
        "ptr", 0, _
        "ptr", 0)
    If @error Or Not $aResult[0] Then Return SetError(3, 0, Binary(""))
   Local $bBinary = DllStructGetData($tOutput, 1)
    If $bReturnBinary Then
        Return $bBinary
    Else
        ; Convert binary to string with specified encoding
        Return BinaryToString($bBinary, $iDecodeType)
    EndIf
EndFunc

; ===================================================================
; Function: _Base64EncodeStr($sInput, $iEncodeType = 4, $bNoCRLF = True)
; Description: Encode string to Base64
; Parameters: $sInput      - String to encode
;             $iEncodeType - 1: ASCII, 4: UTF-8 (default)
;             $bNoCRLF     - True: no line breaks, False: add CRLF
; Return: Base64 encoded string
; Author: Dao Van Trong - TRONG.PRO
; ===================================================================
Func _Base64EncodeStr($sInput, $iEncodeType = 4, $bNoCRLF = True)
    If ($iEncodeType > 4) Or ($iEncodeType < 1) Then $iEncodeType = 4
    Local $bBinary = StringToBinary($sInput, $iEncodeType)
    Return _Base64Encode($bBinary, $bNoCRLF)
EndFunc

; ===================================================================
; Function: _Base64DecodeStr($sInput, $iDecodeType = 4)
; Description: Decode Base64 string to text string
; Parameters:
;   $sInput      - Base64 string to decode
;   $iDecodeType - 1: ASCII, 4: UTF-8 (default)
; Return: Text string
; Author: Dao Van Trong - TRONG.PRO
; ===================================================================
Func _Base64DecodeStr($sInput, $iDecodeType = 4)
    Return _Base64Decode($sInput, False, $iDecodeType)
EndFunc

; ===================================================================
; Base64 Test Suite
; ===================================================================

Func _TestBase64()
    ConsoleWrite(@CRLF & "========================================" & @CRLF)
    ConsoleWrite("Base64 Encode/Decode Test Suite" & @CRLF)
    ConsoleWrite("========================================" & @CRLF & @CRLF)

    Local $iPassCount = 0
    Local $iFailCount = 0

    ; Test 1: ASCII String (default)
    ConsoleWrite("[Test 1] ASCII String (default)" & @CRLF)
    Local $sInput1 = "Hello World"
    Local $sEncoded1 = _Base64EncodeStr($sInput1)
    Local $sDecoded1 = _Base64DecodeStr($sEncoded1)
    ConsoleWrite("  Input:   " & $sInput1 & @CRLF)
    ConsoleWrite("  Encoded: " & $sEncoded1 & @CRLF)
    ConsoleWrite("  Decoded: " & $sDecoded1 & @CRLF)
    If ($sInput1 == $sDecoded1) Then
        ConsoleWrite("  Result:  PASS" & @CRLF & @CRLF)
        $iPassCount += 1
    Else
        ConsoleWrite("  Result:  FAIL" & @CRLF & @CRLF)
        $iFailCount += 1
    EndIf

    ; Test 2: UTF-8 Vietnamese
    ConsoleWrite("[Test 2] UTF-8 Vietnamese" & @CRLF)
    Local $sInput2 = "Xin chào thế giới"
    Local $sEncoded2 = _Base64EncodeStr($sInput2, 4)
    Local $sDecoded2 = _Base64DecodeStr($sEncoded2, 4)
    ConsoleWrite("  Input:   " & $sInput2 & @CRLF)
    ConsoleWrite("  Encoded: " & $sEncoded2 & @CRLF)
    ConsoleWrite("  Decoded: " & $sDecoded2 & @CRLF)
    If ($sInput2 == $sDecoded2) Then
        ConsoleWrite("  Result:  PASS" & @CRLF & @CRLF)
        $iPassCount += 1
    Else
        ConsoleWrite("  Result:  FAIL" & @CRLF & @CRLF)
        $iFailCount += 1
    EndIf

    ; Test 3: UTF-8 Emoji
    ConsoleWrite("[Test 3] UTF-8 Emoji" & @CRLF)
    Local $sInput3 = "😀🎉🚀"
    Local $sEncoded3 = _Base64EncodeStr($sInput3, 4)
    Local $sDecoded3 = _Base64DecodeStr($sEncoded3, 4)
    ConsoleWrite("  Input:   " & $sInput3 & @CRLF)
    ConsoleWrite("  Encoded: " & $sEncoded3 & @CRLF)
    ConsoleWrite("  Decoded: " & $sDecoded3 & @CRLF)
    If ($sInput3 == $sDecoded3) Then
        ConsoleWrite("  Result:  PASS" & @CRLF & @CRLF)
        $iPassCount += 1
    Else
        ConsoleWrite("  Result:  FAIL" & @CRLF & @CRLF)
        $iFailCount += 1
    EndIf

    ; Test 4: Binary Data
    ConsoleWrite("[Test 4] Binary Data" & @CRLF)
    Local $bInput4 = Binary("0x48656C6C6F") ; "Hello" in hex
    Local $sEncoded4 = _Base64Encode($bInput4)
    Local $bDecoded4 = _Base64Decode($sEncoded4, True)
    ConsoleWrite("  Input:   " & $bInput4 & @CRLF)
    ConsoleWrite("  Encoded: " & $sEncoded4 & @CRLF)
    ConsoleWrite("  Decoded: " & $bDecoded4 & @CRLF)
    If ($bInput4 == $bDecoded4) Then
        ConsoleWrite("  Result:  PASS" & @CRLF & @CRLF)
        $iPassCount += 1
    Else
        ConsoleWrite("  Result:  FAIL" & @CRLF & @CRLF)
        $iFailCount += 1
    EndIf

    ; Test 5: ASCII with _Base64Encode (direct binary)
    ConsoleWrite("[Test 5] ASCII with _Base64Encode (direct)" & @CRLF)
    Local $sInput5 = "Direct ASCII"
    Local $sEncoded5 = _Base64Encode($sInput5)
    Local $sDecoded5 = _Base64DecodeStr($sEncoded5, 1)
    ConsoleWrite("  Input:   " & $sInput5 & @CRLF)
    ConsoleWrite("  Encoded: " & $sEncoded5 & @CRLF)
    ConsoleWrite("  Decoded: " & $sDecoded5 & @CRLF)
    If ($sInput5 == $sDecoded5) Then
        ConsoleWrite("  Result:  PASS" & @CRLF & @CRLF)
        $iPassCount += 1
    Else
        ConsoleWrite("  Result:  FAIL" & @CRLF & @CRLF)
        $iFailCount += 1
    EndIf

    ; Test 6: With CRLF (line breaks)
    ConsoleWrite("[Test 6] ASCII with CRLF" & @CRLF)
    Local $sInput6 = "This is a very long string that will trigger CRLF insertion at 76 characters to test line breaking"
    Local $sEncoded6 = _Base64EncodeStr($sInput6, 1, False) ; False = add CRLF
    Local $sDecoded6 = _Base64DecodeStr($sEncoded6, 1)
    ConsoleWrite("  Input:   " & $sInput6 & @CRLF)
    ConsoleWrite("  Encoded:" & @CRLF & $sEncoded6 & @CRLF)
    ConsoleWrite("  Decoded: " & $sDecoded6 & @CRLF)
    If ($sInput6 == $sDecoded6) Then
        ConsoleWrite("  Result:  PASS" & @CRLF & @CRLF)
        $iPassCount += 1
    Else
        ConsoleWrite("  Result:  FAIL" & @CRLF & @CRLF)
        $iFailCount += 1
    EndIf

    ; Test 7: Empty String
    ConsoleWrite("[Test 7] Empty String" & @CRLF)
    Local $sInput7 = ""
    Local $sEncoded7 = _Base64EncodeStr($sInput7)
    Local $sDecoded7 = _Base64DecodeStr($sEncoded7)
    ConsoleWrite("  Input:   (empty)" & @CRLF)
    ConsoleWrite("  Encoded: " & $sEncoded7 & @CRLF)
    ConsoleWrite("  Decoded: (empty)" & @CRLF)
    If $sInput7 = $sDecoded7 Then
        ConsoleWrite("  Result:  PASS" & @CRLF & @CRLF)
        $iPassCount += 1
    Else
        ConsoleWrite("  Result:  FAIL" & @CRLF & @CRLF)
        $iFailCount += 1
    EndIf

    ; Test 8: Special Characters
    ConsoleWrite("[Test 8] Special Characters (ASCII)" & @CRLF)
    Local $sInput8 = "!@#$%^&*()_+-=[]{}|;:',.<>?/~`"
    Local $sEncoded8 = _Base64EncodeStr($sInput8)
    Local $sDecoded8 = _Base64DecodeStr($sEncoded8)
    ConsoleWrite("  Input:   " & $sInput8 & @CRLF)
    ConsoleWrite("  Encoded: " & $sEncoded8 & @CRLF)
    ConsoleWrite("  Decoded: " & $sDecoded8 & @CRLF)
    If ($sInput8 == $sDecoded8) Then
        ConsoleWrite("  Result:  PASS" & @CRLF & @CRLF)
        $iPassCount += 1
    Else
        ConsoleWrite("  Result:  FAIL" & @CRLF & @CRLF)
        $iFailCount += 1
    EndIf

    ; Test 9: Mixed Binary encode/decode
    ConsoleWrite("[Test 9] Mixed Binary Operations" & @CRLF)
    Local $bInput9 = Binary("0x00010203FFFE")
    Local $sEncoded9 = _Base64Encode($bInput9, True)
    Local $bDecoded9 = _Base64Decode($sEncoded9, True)
    ConsoleWrite("  Input:   " & $bInput9 & @CRLF)
    ConsoleWrite("  Encoded: " & $sEncoded9 & @CRLF)
    ConsoleWrite("  Decoded: " & $bDecoded9 & @CRLF)
    If ($bInput9 == $bDecoded9) Then
        ConsoleWrite("  Result:  PASS" & @CRLF & @CRLF)
        $iPassCount += 1
    Else
        ConsoleWrite("  Result:  FAIL" & @CRLF & @CRLF)
        $iFailCount += 1
    EndIf

    ; Test 10: User's simple case
    ConsoleWrite("[Test 10] Simple User Case" & @CRLF)
    Local $sInput10 = "Hello World"
    Local $sEncoded10 = _Base64Encode($sInput10)
    Local $sDecoded10 = _Base64DecodeStr($sEncoded10)
    ConsoleWrite("  Input:   " & $sInput10 & @CRLF)
    ConsoleWrite("  Encoded: " & $sEncoded10 & @CRLF)
    ConsoleWrite("  Decoded: " & $sDecoded10 & @CRLF)
    If ($sInput10 == $sDecoded10) Then
        ConsoleWrite("  Result:  PASS" & @CRLF & @CRLF)
        $iPassCount += 1
    Else
        ConsoleWrite("  Result:  FAIL" & @CRLF & @CRLF)
        $iFailCount += 1
    EndIf

    ; Summary
    ConsoleWrite("========================================" & @CRLF)
    ConsoleWrite("Test Summary" & @CRLF)
    ConsoleWrite("========================================" & @CRLF)
    ConsoleWrite("Total Tests: " & ($iPassCount + $iFailCount) & @CRLF)
    ConsoleWrite("Passed:      " & $iPassCount & @CRLF)
    ConsoleWrite("Failed:      " & $iFailCount & @CRLF)
    ConsoleWrite("========================================" & @CRLF)
EndFunc

; Run test
;_TestBase64()

test function inside!

 

Enjoy my work? Buy me a 🍻 or tip via ❤️ PayPal

Posted

Hi,

I'm getting along very well with this piece of code, and I will use it further, because it´s from a friend of mine 🐵

 

 

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...