Page 1 of 1

Base64 encoder/decoder for Binary data

Posted: 17 Aug 2017, 14:22
by SKAN
A quick rewrite of my old code (posted in archived forum):
https://autohotkey.com/board/topic/8570 ... r-decoder/

Base64Enc() with example

Code: Select all

#NoEnv
#Warn
#SingleInstance, Force
SetWorkingDir %A_ScriptDir% 

File := "ahkicon.png"
If ! FileExist( File )
URLDownloadToFile, http://i.imgur.com/dS56Ewu.png, %File%

FileGetSize, nBytes, %File%
FileRead, Bin, *c %File%
B64Data := Base64Enc( Bin, nBytes, 100, 2 )
MsgBox % Clipboard := B64Data 

Return ;     // end of auto-execcute section //


Base64Enc( ByRef Bin, nBytes, LineLength := 64, LeadingSpaces := 0 ) { ; By SKAN / 18-Aug-2017
Local Rqd := 0, B64, B := "", N := 0 - LineLength + 1  ; CRYPT_STRING_BASE64 := 0x1
  DllCall( "Crypt32.dll\CryptBinaryToString", "Ptr",&Bin ,"UInt",nBytes, "UInt",0x1, "Ptr",0,   "UIntP",Rqd )
  VarSetCapacity( B64, Rqd * ( A_Isunicode ? 2 : 1 ), 0 )
  DllCall( "Crypt32.dll\CryptBinaryToString", "Ptr",&Bin, "UInt",nBytes, "UInt",0x1, "Str",B64, "UIntP",Rqd )
  If ( LineLength = 64 and ! LeadingSpaces )
    Return B64
  B64 := StrReplace( B64, "`r`n" )        
  Loop % Ceil( StrLen(B64) / LineLength )
    B .= Format("{1:" LeadingSpaces "s}","" ) . SubStr( B64, N += LineLength, LineLength ) . "`n" 
Return RTrim( B,"`n" )    
}

Base64Dec() with example

Code: Select all

#NoEnv
#Warn
#SingleInstance, Force
SetWorkingDir %A_ScriptDir% 


Base64ImageData := "
( LTrim Join
  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
)"

nBytes := Base64Dec( Base64ImageData, Bin )

File := FileOpen("ahkiconnew.png", "w")
File.RawWrite(Bin, nBytes)
File.Close()

Gui, Add, Picture, w256 h256, ahkiconnew.png
Gui, Show
Return ;    // end of auto-execcute section //




Base64Dec( ByRef B64, ByRef Bin ) {  ; By SKAN / 18-Aug-2017
Local Rqd := 0, BLen := StrLen(B64)                 ; CRYPT_STRING_BASE64 := 0x1
  DllCall( "Crypt32.dll\CryptStringToBinary", "Str",B64, "UInt",BLen, "UInt",0x1
         , "UInt",0, "UIntP",Rqd, "Int",0, "Int",0 )
  VarSetCapacity( Bin, 128 ), VarSetCapacity( Bin, 0 ),  VarSetCapacity( Bin, Rqd, 0 )
  DllCall( "Crypt32.dll\CryptStringToBinary", "Str",B64, "UInt",BLen, "UInt",0x1
         , "Ptr",&Bin, "UIntP",Rqd, "Int",0, "Int",0 )
Return Rqd
}

Testing Base64 encoded image in WEB control. ( tested and works in Win XP IE6 )

Code: Select all

#NoEnv
#Warn
#SingleInstance, Force

Base64ImageData := "
( LTrim Join
  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
)" 

Gui, Add, ActiveX, w300 h300 vDoc, HtmlFile
Doc.Write( "<img src=""data:image/png;base64, " Base64ImageData """/>" )
Gui, Show,, ActiveX Base64 Image Test
Return

The image used in above examples:
http://i.imgur.com/dS56Ewu.png (2543 bytes)
Image
Also see: Base64ToComByteArray() :: Include image in script and display it with WIA 2.0

Re: Base64 encoder/decoder for Binary data

Posted: 17 Aug 2017, 14:59
by burque505
Thank you, SKAN.
Tested on Win7 x64, AHK_H 1.25.02, all three scripts work perfectly.
Regards,
burque505

Re: Base64 encoder/decoder for Binary data

Posted: 17 Aug 2017, 18:21
by geek
See also libcrypt.ahk's Base64 encoder (requires its BinStr encoder).

Re: Base64 encoder/decoder for Binary data

Posted: 19 Aug 2017, 18:05
by burque505
GeekDude, thanks for that too!
burque505

Re: Base64 encoder/decoder for Binary data

Posted: 05 Sep 2017, 07:42
by jNizM
Just for reference base64.ahk (GitHub) (Unicode / UTF-8 - like online tools does)

Re: Base64 encoder/decoder for Binary data

Posted: 06 Apr 2018, 10:39
by HillaryDev
can anyone explain why when I output the base 64 to a edit box on my gui it leaves spaces in between each line?

Re: Base64 encoder/decoder for Binary data

Posted: 08 Apr 2018, 15:33
by iseahound
On the Documentation page it says that for the 3rd parameter:

Code: Select all

0x00000001    CRYPT_STRING_BASE64    Base64, without headers.
0x40000000    CRYPT_STRING_NOCRLF    Do not append any new line characters to the encoded string. The default behavior is to use a carriage return/line feed (CR/LF) pair (0x0D/0x0A) to represent a new line.
So change the 0x1 in two DllCall to 0x40000001 DllCall( "Crypt32.dll\CryptBinaryToString", "Ptr",&Bin, "UInt",nBytes, "UInt",0x40000001, "Str",B64, "UIntP",Rqd )

Why is that the default behavior? Only Microsoft knows.

Re: Base64 encoder/decoder for Binary data

Posted: 08 Apr 2018, 15:44
by jeeswg
Do note this re. CRYPT_STRING_NOCRLF:
CryptBinaryToString function (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Windows Server 2003 and Windows XP: This value is not supported.

Re: Base64 encoder/decoder for Binary data

Posted: 08 Apr 2018, 16:40
by HillaryDev
iseahound wrote:On the Documentation page it says that for the 3rd parameter:

Code: Select all

0x00000001    CRYPT_STRING_BASE64    Base64, without headers.
0x40000000    CRYPT_STRING_NOCRLF    Do not append any new line characters to the encoded string. The default behavior is to use a carriage return/line feed (CR/LF) pair (0x0D/0x0A) to represent a new line.
So change the 0x1 in two DllCall to 0x40000001 DllCall( "Crypt32.dll\CryptBinaryToString", "Ptr",&Bin, "UInt",nBytes, "UInt",0x40000001, "Str",B64, "UIntP",Rqd )

Why is that the default behavior? Only Microsoft knows.

When I output the base64 to a text box (not edit box, just text lable that is not single line) it adds big spaces between each line even after updating the dllcall :thumbdown:

Re: Base64 encoder/decoder for Binary data

Posted: 02 Jun 2018, 16:48
by Ralf28
I get an error when I want a .png file decode

-----------------------------------------------

Error at Line 5.

Error: Continuation section too long.

-----------------------------------------------

It is a png. with the pixel size "900x505"

Does anyone know what this is and how to fix it that works?

Re: Base64 encoder/decoder for Binary data

Posted: 15 Dec 2019, 07:02
by murataygun
This post is very missleading. That encoding function has problems it encodes like this;

Code: Select all


  AAAAAAAA4CcPADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgKA8AlAAAAAAAAAAAAAAAAHAMALgOAAAAAAAAAAAAAAAAAAAA
  AAAAAAAAAAAAAAAudGV4dAAAAOxQDAAAEAAAAFIMAAAEAAAAAAAAAAAAAAAAAAAgAABgLnJkYXRhAACwkAMAAHAMAACSAwAAVgwA
  AAAAAAAAAAAAAAAAQAAAQC5kYXRhAAAAhJwAAAAQEAAAOgAAAOgPAAAAAAAAAAAAAAAAAEAAAMAucGRhdGEAABhyAAAAsBAAAHQA
  AAAiEAAAAAAAAAAAAAAAAABAAABALmdmaWRzAADkAAAAADARAAACAAAAlhAAAAAAAAAAAAAAAAAAQAAAQC5yc3JjAAAACK8AAABA
  EQAAsAAAAJgQAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEiD7Cj/FcZlDACJBYByEABIg8Qow8zMzMzM
  zMzMzMzMSIlcJAhXSIPsIDPJ/xXmagwASIvIulgAAABIi/j/FbVhDABIi9czyYvY/xXAagwAiR0+chAASItcJDBIg8QgX8PMzMzM
  zMzMzMzMzMzMzMxIg+wo6MeKAQBIjQ3wTwwASIPEKOkzZgoAzMzMzMzMzOmbYgEAzMzMzMzMzMzMzMxIjQ3ZTwwA6RBmCgDMzMzM
  SIPsKP8VXmUMAIkF2H8QAEiDxCjDzMzMzMzMzMzMzMxIg+wo/xU+ZQwAiQW8fxAASIPEKMPMzMzMzMzMzMzMzIsFpn8QAIkFpH8Q
  AMPMzMyLBZZ/EACJBZh/EADDzMzMSIPsKEiNDQVLDgD/FU9kDABIi8hIjRXVSg4A/xVPZAwASIkFcH8QAEiDxCjDzMzMSIPsKEiN
  DdVKDgD/FR9kDABIi8hIjRXVSg4A/xUfZAwASIkFSH8QAEiDxCjDzMzMSIPsKEiNDUV/EADo4OkAAA9XwMcFO38QAAEAAAAPV8lm
  D38FOH8QAEiNBVnNDgBmD38NOX8QAEiNDTJPDABmD38FOn8QAEiJBQN/EABIg8Qo6fZkCgDMzMzMzMzMzMzMSIPsKP8VbmIMAIkF
  2H4QAEiDxCjDzMzMzMzMzMzMzMxAV0iD7CBIiwVbCBAASIv6gLg1AQAARHUQQbgKAAAASIPEIF/pm6AKAEiJXCQwSIvfSIXJeQ+4
  LQAAAEiNWgJmiQJI99lBuBAAAADHAzAAeABIjVME6GqgCgBIiwUHCBAAgLg1AQAASHUKSI1LBP8V1GoMAEiLx0iLXCQwSIPEIF/D
  zMzMzMzMzMzMzMzMzMxIiVwkCEiJdCQQV0iD7CCAeSMAQQ+2+EiL8kiL2XUESItZEA+2QyGoAnQOSIsLJD2IQyFIiwH/UBCAYyGL
It must be a 'one line' string and you cant decode anywhere even with that decode function.


Edit: @tmplinshi Covered misunderstandings with his perfectly working script here;
https://www.autohotkey.com/boards/viewtopic.php?p=305766#p305766

Re: Base64 encoder/decoder for Binary data

Posted: 15 Dec 2019, 08:21
by guest3456
murataygun wrote:
15 Dec 2019, 07:02
This post is very missleading. That encoding function has problems it encodes like this;

Code: Select all


  AAAAAAAA4CcPADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgKA8AlAAAAAAAAAAAAAAAAHAMALgOAAAAAAAAAAAAAAAAAAAA
  AAAAAAAAAAAAAAAudGV4dAAAAOxQDAAAEAAAAFIMAAAEAAAAAAAAAAAAAAAAAAAgAABgLnJkYXRhAACwkAMAAHAMAACSAwAAVgwA
  AAAAAAAAAAAAAAAAQAAAQC5kYXRhAAAAhJwAAAAQEAAAOgAAAOgPAAAAAAAAAAAAAAAAAEAAAMAucGRhdGEAABhyAAAAsBAAAHQA
  AAAiEAAAAAAAAAAAAAAAAABAAABALmdmaWRzAADkAAAAADARAAACAAAAlhAAAAAAAAAAAAAAAAAAQAAAQC5yc3JjAAAACK8AAABA
  EQAAsAAAAJgQAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEiD7Cj/FcZlDACJBYByEABIg8Qow8zMzMzM
  zMzMzMzMSIlcJAhXSIPsIDPJ/xXmagwASIvIulgAAABIi/j/FbVhDABIi9czyYvY/xXAagwAiR0+chAASItcJDBIg8QgX8PMzMzM
  zMzMzMzMzMzMzMxIg+wo6MeKAQBIjQ3wTwwASIPEKOkzZgoAzMzMzMzMzOmbYgEAzMzMzMzMzMzMzMxIjQ3ZTwwA6RBmCgDMzMzM
  SIPsKP8VXmUMAIkF2H8QAEiDxCjDzMzMzMzMzMzMzMxIg+wo/xU+ZQwAiQW8fxAASIPEKMPMzMzMzMzMzMzMzIsFpn8QAIkFpH8Q
  AMPMzMyLBZZ/EACJBZh/EADDzMzMSIPsKEiNDQVLDgD/FU9kDABIi8hIjRXVSg4A/xVPZAwASIkFcH8QAEiDxCjDzMzMSIPsKEiN
  DdVKDgD/FR9kDABIi8hIjRXVSg4A/xUfZAwASIkFSH8QAEiDxCjDzMzMSIPsKEiNDUV/EADo4OkAAA9XwMcFO38QAAEAAAAPV8lm
  D38FOH8QAEiNBVnNDgBmD38NOX8QAEiNDTJPDABmD38FOn8QAEiJBQN/EABIg8Qo6fZkCgDMzMzMzMzMzMzMSIPsKP8VbmIMAIkF
  2H4QAEiDxCjDzMzMzMzMzMzMzMxAV0iD7CBIiwVbCBAASIv6gLg1AQAARHUQQbgKAAAASIPEIF/pm6AKAEiJXCQwSIvfSIXJeQ+4
  LQAAAEiNWgJmiQJI99lBuBAAAADHAzAAeABIjVME6GqgCgBIiwUHCBAAgLg1AQAASHUKSI1LBP8V1GoMAEiLx0iLXCQwSIPEIF/D
  zMzMzMzMzMzMzMzMzMxIiVwkCEiJdCQQV0iD7CCAeSMAQQ+2+EiL8kiL2XUESItZEA+2QyGoAnQOSIsLJD2IQyFIiwH/UBCAYyGL
It must be a 'one line' string and you cant decode anywhere even with that decode function.
calling the post "very misleading" is very misleading.

you must have missed this post in the thread:
https://www.autohotkey.com/boards/viewtopic.php?p=211345#p211345

Re: Base64 encoder/decoder for Binary data

Posted: 16 Dec 2019, 06:22
by just me
Besides the CRYPT_STRING_NOCRLF option guest3456 referred to, why do you think it's a problem?

Re: Base64 encoder/decoder for Binary data

Posted: 01 Feb 2020, 23:47
by guest3456
SKAN wrote:
17 Aug 2017, 14:22

Code: Select all

Base64Enc( ByRef Bin, nBytes, LineLength := 64, LeadingSpaces := 0 ) { ; By SKAN / 18-Aug-2017
Local Rqd := 0, B64, B := "", N := 0 - LineLength + 1  ; CRYPT_STRING_BASE64 := 0x1
  DllCall( "Crypt32.dll\CryptBinaryToString", "Ptr",&Bin ,"UInt",nBytes, "UInt",0x1, "Ptr",0,   "UIntP",Rqd )  ; <--------- Rqd
  VarSetCapacity( B64, Rqd * ( A_Isunicode ? 2 : 1 ), 0 )
  DllCall( "Crypt32.dll\CryptBinaryToString", "Ptr",&Bin, "UInt",nBytes, "UInt",0x1, "Str",B64, "UIntP",Rqd )  ; <--------- Rqd
  If ( LineLength = 64 and ! LeadingSpaces )
    Return B64
  B64 := StrReplace( B64, "`r`n" )        
  Loop % Ceil( StrLen(B64) / LineLength )
    B .= Format("{1:" LeadingSpaces "s}","" ) . SubStr( B64, N += LineLength, LineLength ) . "`n" 
Return RTrim( B,"`n" )    
}
@SKAN , @just me

you guys have both used this func in your scripts in the past. my question is about the last param which first returns the size, and then on the second call passes the size in. SKAN is using variable Rqd for this.

but, if i'm reading MSDN correct:
https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptbinarytostringa wrote: pcchString

A pointer to a DWORD variable that contains the size, in TCHARs, of the pszString buffer. If pszString is NULL, the function calculates the length of the return string (including the terminating null character) in TCHARs and returns it in this parameter. If pszString is not NULL and big enough, the function converts the binary data into a specified string format including the terminating null character, but pcchString receives the length in TCHARs, not including the terminating null character.
i think the correct way should should be Rqd-1..?

however, i just tested it, and it seems i'm able to pass any number at all, and it still converts correctly

Re: Base64 encoder/decoder for Binary data

Posted: 02 Feb 2020, 00:04
by Helgef
It should be Rqd, not Rqd-1

Cheers.

Re: Base64 encoder/decoder for Binary data

Posted: 02 Feb 2020, 00:57
by guest3456
Helgef wrote:
02 Feb 2020, 00:04
It should be Rqd, not Rqd-1
can you explain why? the msdn says that that param "receives the number of tchars not including the null terminator", and after the first call, it returned the number WITH the null terminator

edit:
ahhh "receives" means its also an output param on the 2nd call too... msgbox'ing both before and after the 2nd call shows a decrease by -1, meaning the dllcall modified that as output var too

Re: Base64 encoder/decoder for Binary data

Posted: 02 Feb 2020, 01:11
by Helgef
When the pszString buffer is not null, the parameter must be,
the size, in TCHARs, of the pszString buffer.
The buffer must include room for the null terminator, since the string must be null terminated. This is exactly what you get from the first call.

Edit, yes :thumbup:

Edit 2, cheers.

Re: Base64 encoder/decoder for Binary data

Posted: 28 Jul 2021, 07:24
by SirSocks
Thank you for the function and examples. It works perfectly for me. :clap:

Re: Base64 encoder/decoder for Binary data

Posted: 06 Nov 2021, 12:20
by keraynopoylos
Apologies for a question on the above code - on which I have no insight at all (I mean how the DllCall works).
[Update: I have now spent over 3 hours trying to figure out the dllcall paramaters and trial/error but still nada...
For some reason, the Rqd variable gets a value higher than it should - if I manually set the B64 as double the length of the string_to_be_decoded, it works fine.]

Therefore, I shamelessly tried to use as-is for my needs (well, there's always some guilt when using code one doesn't know why it works).

What I was trying to do is to convert a variable to binary and store in a file and then retrieve it in the future when needed. It is indeed a password and wanted to convert to binary as means of preventing someone from opening a text editor and just seeing it; I know it is still easy for someone to read it - a few more steps will be taken to "scramble" the actual password in the final version.

I have the following 2 scripts - one asks for input (the password) and then uses the above to convert to binary and store - the second just does the opposite, again, based on the above.

The problem is that the output differs from the input:
Depending on the password length it may be ok or it may come with a "=" at the end and sometimes the previous character altered too - for example any 20-character long string is just fine but any 10-character long one is not ("12345678901234567890" comes back fine but "1234567890" returns as "123456789w=="

Storing script:

Code: Select all

#NoEnv
#Warn
#SingleInstance, Force
SetWorkingDir %A_ScriptDir% 



inputbox, initvar, PasswordEncode, Enter passwork to encode, , 180, 130
if ErrorLevel
{
  return
}
else
{

nBytes := Base64Dec( initvar, Bin )

File := FileOpen("thepasswordfile.bin", "w")
File.RawWrite(Bin, nBytes)
File.Close()

}
Return ;    // end of auto-execcute section //



Base64Dec( ByRef B64, ByRef Bin ) {  ; By SKAN / 18-Aug-2017
Local Rqd := 0, BLen := StrLen(B64)                 ; CRYPT_STRING_BASE64 := 0x1
  DllCall( "Crypt32.dll\CryptStringToBinary", "Str",B64, "UInt",BLen, "UInt", 0x1
         , "UInt",0, "UIntP",Rqd, "Int",0, "Int",0 )
  VarSetCapacity( Bin, 128 ), VarSetCapacity( Bin, 0 ),  VarSetCapacity( Bin, Rqd, 0 )
  DllCall( "Crypt32.dll\CryptStringToBinary", "Str",B64, "UInt",BLen, "UInt", 0x1
         , "Ptr",&Bin, "UIntP",Rqd, "Int",0, "Int",0 )
Return Rqd
}
Retrieving script:

Code: Select all

#NoEnv
#Warn
#SingleInstance, Force
SetWorkingDir %A_ScriptDir% 

^y::
File := "thepasswordfile.bin"
If ! FileExist( File )
msgbox, file does not exist

FileGetSize, nBytes, %File%
FileRead, Bin, *c %File%
B64Data := Base64Enc( Bin, nBytes, 100, 2 )
;MsgBox % B64Data 
Send, %B64Data%

Return ;     // end of auto-execcute section //


Base64Enc( ByRef Bin, nBytes, LineLength := 64, LeadingSpaces := 0 ) { ; By SKAN / 18-Aug-2017
Local Rqd := 0, B64, B := "", N := 0 - LineLength + 1  ; CRYPT_STRING_BASE64 := 0x1
  DllCall( "Crypt32.dll\CryptBinaryToString", "Ptr",&Bin ,"UInt",nBytes, "UInt", 0x40000001, "Ptr",0,   "UIntP",Rqd )
  VarSetCapacity( B64, Rqd * ( A_Isunicode ? 2 : 1 ), 0 )
  DllCall( "Crypt32.dll\CryptBinaryToString", "Ptr",&Bin, "UInt",nBytes, "UInt", 0x40000001, "Str",B64, "UIntP",Rqd )
  If ( LineLength = 64 and ! LeadingSpaces )
    Return B64
  B64 := StrReplace( B64, "`r`n" )        
  Loop % Ceil( StrLen(B64) / LineLength )
    B .= Format("{1:" LeadingSpaces "s}","" ) . SubStr( B64, N += LineLength, LineLength ) . "`n" 
Return RTrim( B,"`n" )    
}
Thanks for any explanation.

Re: Base64 encoder/decoder for Binary data

Posted: 08 Nov 2021, 22:09
by keraynopoylos
Nevermind.
Sill don't understand how the dll call works but played around for a few hours with the example of another member and at least I managed to get what I need.