AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Base64 coder/decoder
Goto page Previous  1, 2, 3  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
guest123
Guest





PostPosted: Tue Jul 04, 2006 8:55 am    Post subject: Reply with quote

Sorry to be such a noob Embarassed but if i want to use this scipt to encode some text, where do i put it, and more to the point, can you explain how I use this?

cheers
guest
Back to top
PhiLho



Joined: 27 Dec 2005
Posts: 6836
Location: France (near Paris)

PostPosted: Tue Jul 04, 2006 10:10 am    Post subject: Reply with quote

Copy/Paste the Base64Encode function in your code, call it like this: encoded := Base64Encode(textToEncode)
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Tue Jul 04, 2006 12:41 pm    Post subject: Reply with quote

Sorry i dont understand, could you post an example of what the script should look like if for example i wanted to encode the word ''password''
Back to top
PhiLho



Joined: 27 Dec 2005
Posts: 6836
Location: France (near Paris)

PostPosted: Tue Jul 04, 2006 1:56 pm    Post subject: Reply with quote

I believe you should learn to walk before running...
I don't know what you are trying to do, but if you don't understand how to assign a string to a variable and call a function, you should first read the easy tutorial before going further.
I don't try to be snappy or something, it is just that you can't do much if you don't know such basic things.
BTW, don't use Base64 to hide passwords, this is not really encryption, anybody with base computing knowledge would be able to find your password.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
Guest123
Guest





PostPosted: Tue Jul 04, 2006 3:20 pm    Post subject: Reply with quote

Don't worry, fixed it now, thanks for your help.
Very Happy
Back to top
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Sun Jul 09, 2006 7:10 pm    Post subject: Reply with quote

I added a version to the original post, to handle binary buffers as well as AHK strings.
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Mon Jul 17, 2006 6:55 pm    Post subject: Reply with quote

If someone is interested in direct conversion between hex and base64, here is a script.
Back to top
View user's profile Send private message
John Anfdrew
Guest





PostPosted: Wed Jul 19, 2006 8:12 am    Post subject: Can this output text? Reply with quote

Sorry if this post is bit disjoined, but it's kinda late.

I tried to use it to test some other Base64 string generated by another program, Second Life. However, It won't display the results correctly.

Code:
   Locked := true
   Gui, Add, Edit,w250  +Center vKey
   Gui, Add, Button,w250  +Center , Unlock
   Gui, Show, Center,

ButtonUnlock:
GuiControlGet, Key
SubmitedKeyDecoded := InvBase64(Key)
SubmitedEncoded:= Base64(Key)
MsgBox, %SubmitedKeyDecoded %
MsgBox, %SubmitedEncoded%
return



Is what I added to the top, But I I get back are blank responses and "?????" Is ther something I need to do or an I totally misunderstanding with script?

And is there a imple way to Xor these strings?

I want to eventually use it in conjunction with:
http://secondlife.com/badgeo/wakka.php?wakka=llXorBase64Strings

I really novice when it comes to this sort of thing. ^_^;[/url]
Back to top
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Wed Jul 19, 2006 4:02 pm    Post subject: Reply with quote

For experimenting this looks better:
Code:
StringCaseSense On
Chars = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

Gui Add, Edit, w250 vKey
Gui Add, Button, w120, Encode
Gui Add, Button, w120 xp+130, Decode
Gui Show, Center
Return

ButtonClose:
ButtonEscape:
ExitApp

ButtonEncode:
  GuiControlGet Key
  GuiControl,,Key, % Base64(Key)
return

ButtonDecode:
  GuiControlGet Key
  GuiControl,,Key, % InvBase64(Key)
return

Base64(string) {
   Loop Parse, string
   {
      If Mod(A_Index,3) = 1
         buffer := Asc(A_LoopField) << 16
      Else If Mod(A_Index,3) = 2
         buffer += Asc(A_LoopField) << 8
      Else {
         buffer += Asc(A_LoopField)
         out := out . Code(buffer>>18) . Code(buffer>>12) . Code(buffer>>6) . Code(buffer)
      }
   }
   If Mod(StrLen(string),3) = 0
      Return out
   If Mod(StrLen(string),3) = 1
      Return out . Code(buffer>>18) . Code(buffer>>12) "=="
   Return out . Code(buffer>>18) . Code(buffer>>12) . Code(buffer>>6) "="
}

InvBase64(code) {
   StringReplace code, code, =,,All
   Loop Parse, code
   {
      If Mod(A_Index,4) = 1
         buffer := DeCode(A_LoopField) << 18
      Else If Mod(A_Index,4) = 2
         buffer += DeCode(A_LoopField) << 12
      Else If Mod(A_Index,4) = 3
         buffer += DeCode(A_LoopField) << 6
      Else {
         buffer += DeCode(A_LoopField)
         out := out . Chr(buffer>>16) . Chr(255 & buffer>>8) . Chr(255 & buffer)
      }
   }
   If Mod(StrLen(code),4) = 0
      Return out
   If Mod(StrLen(code),4) = 2
      Return out . Chr(buffer>>16)
   Return out . Chr(buffer>>16) . Chr(255 & buffer>>8)
}

Code(i) {   ; <== Chars[i & 63], 0-base index
   Global Chars
   StringMid i, Chars, (i&63)+1, 1
   Return i
}

DeCode(c) { ; c = a char in Chars ==> position [0,63]
   Global Chars
   Return InStr(Chars,c,1) - 1
}
Back to top
View user's profile Send private message
Richard
Guest





PostPosted: Wed Feb 28, 2007 7:24 pm    Post subject: Place base64 Code in the autoexecute section Reply with quote

Hi,

I just want to point out for anyone having trouble with this script that it MUSt be placed in the autoexecute section of the script (i.e. before any labels, hotkeys etc.)

Otherwise, Chars will not be a global, and all the results will be BLANK!
Back to top
TT2009
Guest





PostPosted: Wed Oct 21, 2009 6:21 am    Post subject: Can't get this to work Reply with quote

Hi Laszlo,

I can't get your second script to work. Perhaps it is because I don't understand how to use it? What are the bin, n, and code variables supposed to be?

Also your first script doesn't seem to handle punctuation: !@#$%^&* etc. Does the second one, being binary, handle these characters?

Cheers,
TT
Back to top
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Wed Oct 21, 2009 5:21 pm    Post subject: Reply with quote

These scripts are obsolete now. In XP+ you should use the Windows Crypto API, as Titan discovered:
Code:
;;;;; ----- Binary to base64/formatted-HEX conversion by the Crypto API, for XP+  (2HEX, 2Base64)
; http://msdn.microsoft.com/en-us/library/aa380285(VS.85).aspx
; http://www.autohotkey.com/forum/viewtopic.php?p=238120#238120

; fmt = 1:base64, 4:hex-table, 5:hex+ASCII, 10:offs+hex, 11:offs+hex+ASCII, 12:raw-hex

BinaryToString(ByRef bin, sz=0, fmt=12) {   ; return base64 or formatted-hex
   n := sz>0 ? sz : VarSetCapacity(bin)
   DllCall("Crypt32.dll\CryptBinaryToStringA", UInt,&bin, UInt,n, UInt,fmt, UInt,0, UIntP,cp, "CDECL UInt") ; get size
   VarSetCapacity(str,cp)
   DllCall("Crypt32.dll\CryptBinaryToStringA", UInt,&bin, UInt,n, UInt,fmt, UInt,&str, UIntP,cp, "CDECL UInt")
   Return str
}

StringToBinary(ByRef bin, hex, fmt=12) {    ; return length, result in bin
   DllCall("Crypt32.dll\CryptStringToBinaryA", UInt,&hex, UInt,StrLen(hex), UInt,fmt, UInt,0, UIntP,cp, UInt,0,UInt,0,"CDECL UInt") ; get size
   VarSetCapacity(bin,cp)
   DllCall("Crypt32.dll\CryptStringToBinaryA", UInt,&hex, UInt,StrLen(hex), UInt,fmt, UInt,&bin, UIntP,cp, UInt,0,UInt,0,"CDECL UInt")
   Return cp
}
                                            ; TEST
VarSetCapacity(bin,100,122)                 ; 100 z-chars
fmt = 11                                    ; table: offs+hex+ASCII
MsgBox % hex:= BinaryToString(bin,100,fmt)  ; encode

len := StringToBinary(bin1,hex,fmt)         ; decode
VarSetCapacity(bin1,-1)                     ; use only with string in bin1
bin1 := SubStr(bin1,1,len)                  ; strip of garbage at the end
MsgBox %len%: %bin1%                        ; show len, original data
Back to top
View user's profile Send private message
Jamie



Joined: 26 Mar 2010
Posts: 129

PostPosted: Fri May 21, 2010 12:05 am    Post subject: Reply with quote

For some reason these dll calls are not working for me. I'm on Vista and I've checked the inputs and return values and everything appears to be okay except for the output value. The space allocated is what i would expect, and the function is returning nonzero for success. Except that the output variable is blank.

So I'm going to go back to the AHK version.

This will probably be the smallest nit-pick ever, but in the binary version of Base64Decode, I think this:
Code:
   VarSetCapacity(bin, 3*StrLen(code)//4, 0)
   StringReplace code, code, =,,All

should instead be this:
Code:
   StringReplace code, code, =,,All
   VarSetCapacity(bin, 3*StrLen(code)//4, 0)

In the first snippet, the variable capacity is larger than the number of encoded bytes if the base64 string ends with trailing = characters.

The variable capacity appears to work as a way to keep track of the number of bytes in a binary blob. However, this is extremely dangerous because there is no guarantee that the capacity will be equal to the requested capacity -- it may be larger. But it just happens to be equal in all the cases that have mattered so far.

(As a side note, perhaps the use of VarSetCapacity to query the capacity should carry strong warnings, as these may easily lead to unsafe code.)

Nonetheless, I'm abandoning the use of variable capacity to keep track of blob sizes, and keeping track of them manually, so I've also changed Base64Decode to return the number of bytes decoded:
Code:
Base64Decode(ByRef bin, code) {
   StringReplace code, code, =,,All
   decodedbytes := 3*StrLen(code)//4
   VarSetCapacity(bin, decodedbytes, 0)
   ...
   return decodedbytes
}
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Fri May 21, 2010 6:28 pm    Post subject: Reply with quote

No, you need the VarSetCapacity and StringReplace in the original order in Base64Decode, to force rounding up to the used length. In Base64Encode the allocated memory is only used, if the size is not given, or if it was wrong. There is nothing unsafe with it: if the capacity is too large, you just encode some garbage in the end of the allocated buffer.
Back to top
View user's profile Send private message
Jamie



Joined: 26 Mar 2010
Posts: 129

PostPosted: Fri May 21, 2010 10:25 pm    Post subject: Reply with quote

Hmm, the way I see it, if you were to have "xx==" then there are 4 characters but only 2 base64 digits, so 3*StrLen//4 will return 3 decoded bytes or 6//4 = 1 decoded bytes depending on whether you strip out the equal signs first.

In the case of a string ending in "xxx=", there are again 4 characters but 3 base64 digits, and 3*strlen//4 will be either 3 decoded bytes or 9//4 = 2 decoded bytes.

If there are not a multiple of 4 base64 digits, then in the very last base64 digit, only some of the six available bits are used. So the actual length in bytes should be rounded down from the number of base64 digits times 3/4.

Usually extra space at the end is not a problem but if for some reason you do need the exact size, I still think you need to compute it by stripping out the equals signs first.

The general practice of using capacity to keep track of exact blob size is probably okay but could potentially be hazardous. But I agree there is nothing unsafe with the functions, since as you mentioned they do not require you to use the capacity as an indicator of blob size.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group