Page 1 of 1
Decoding Base64 image failed
Posted: 13 Dec 2018, 05:01
by afe
Hello,
I tried to decode a Base64 encoding of an image, but it didn't work. Where is the mistake?
Thanks!
Code: Select all
Base64Char := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Base64Index(c)
{
Global Base64Char
return InStr(Base64Char, c, CaseSensitive) - 1
}
Base64Decode(str, ByRef Bytes)
{
Bytes := 0
str := StrReplace(str, "=")
Loop Parse, str
{
if Mod(A_Index, 4) = 1
buffer := Base64Index(A_LoopField) << 18
else If Mod(A_Index, 4) = 2
{
buffer += Base64Index(A_LoopField) << 12
++Bytes
}
else If Mod(A_Index, 4) = 3
{
buffer += Base64Index(A_LoopField) << 6
++Bytes
}
else
{
buffer += Base64Index(A_LoopField)
r := r << 24 + buffer
++Bytes
}
}
if Mod(StrLen(code),4) = 0
return r
if Mod(StrLen(code),4) = 2
return r << 8 + buffer >> 16
return r << 16 + buffer >> 8
}
Base64Str := "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgARCAACAAIDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAG/B//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQ8//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z"
Var := Base64Decode(Base64Str, Bytes)
File := FileOpen("test.jpg", "w")
File.RawWrite(Var, Bytes)
File.Close()
return
Re: Decoding Base64 image failed
Posted: 13 Dec 2018, 05:37
by John
You base64 string doesn't decode into anything,
https://codebeautify.org/base64-to-image-converter
The script didn't seem to work either, don't know why. If you justn eed to get it working and don't want/need to understand the unerlying issues then try this function instead
https://autohotkey.com/board/topic/8570 ... r-decoder/ used it before and works fine.
Posted: 13 Dec 2018, 05:44
by swagfag
no. its an image of a white square.
id say its the function, where did u get it? did u write this urself?
use this instead
https://autohotkey.com/boards/viewtopic.php?t=35964
Re: Decoding Base64 image failed
Posted: 13 Dec 2018, 07:02
by afe
Yex, but there is a problem with thinking.
Base64 converts every 3 binary bytes of the image into 4 Base64 characters. In turn, decoding requires converting every 4 Base64 characters to 3 binary bytes.
But the problem arises, I mistakenly save these converted binary bytes into a variable "r". This may be the wrong place, or the idea is completely wrong. I'm confused.
What you can't figure out is if you combine these binary bytes into the same binary code as the original picture.
Yes, I have read some articles, but I still have not learned to use DllCall now, so I want to avoid it.
Or if the value of a variable is a string of binary code of an image, how can I save it as an image?
Re: Decoding Base64 image failed Topic is solved
Posted: 14 Dec 2018, 06:48
by hd0202
here is my version (not tested if input is not multiple of 4):
Code: Select all
Base64Char := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Base64Index(c)
{
Global Base64Char
return InStr(Base64Char, c, true) - 1
}
Base64Decode(str, ByRef var)
{
Bytes := 1
loop, % strlen(str) / 4
{
buffer := substr(str, (bytes - 1) * 4 + 1, 4)
r := 0
loop, 4
r := (r << 6) + base64index(substr(buffer, a_index , 1))
numput(x := r & 255, var, (bytes - 1) * 3 + 2, "uchar")
numput(y := r >> 8 & 255, var, (bytes - 1) * 3 + 1, "uchar")
numput(z := r >> 16 & 255, var, (bytes - 1) * 3, "uchar")
bytes++
}
; if Mod(StrLen(code),4) = 0
; return r
; if Mod(StrLen(code),4) = 2
; return r << 8 + buffer >> 16
; return r << 16 + buffer >> 8
}
Base64Str := "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgARCAACAAIDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAG/B//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQ8//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z"
v := varsetcapacity(var, strlen(base64str) / 4 * 3)
Base64Decode(Base64Str, var)
File := FileOpen("test.jpg", "w")
File.RawWrite(Var, v)
File.Close()
return
Hubert
Re: Decoding Base64 image failed
Posted: 15 Dec 2018, 06:52
by afe
@hd0202 , thank you very much! Great, numput is exactly what I want. Thank you!
Re: Decoding Base64 image failed
Posted: 15 Dec 2018, 09:53
by afe
I modified it a bit and tried to use "RtlFillMemory" but it still failed. I don't know where it is wrong.
===========
It works now.
Code: Select all
Base64CharIndex(c)
{
static Base64CharSet := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
return InStr(Base64CharSet, c, 1) - 1
}
WriteToMemory(ByRef bin, Fill)
{
global pos
DllCall("RtlFillMemory"
, "ptr", &bin + pos
, "int", 1
, "uchar", Fill)
++pos
return
}
Base64Decode(Base64Code, ByRef bin)
{
Base64CodeLength := StrLen(Base64Code) // 4 * 3
if ( RegExMatch(Base64Code, "=$") )
{
if ( RegExMatch(Base64Code, "==$") )
binSize := Base64CodeLength - 2
else
binSize := Base64CodeLength - 1
}
else
binSize := Base64CodeLength
VarSetCapacity(bin, binSize)
Base64Code := StrReplace(Base64Code, "=")
Loop, Parse, Base64Code
{
Base64CharIndexValue := Base64CharIndex(A_LoopField)
n := A_Index & 3
if ( n = 1 )
buffer := Base64CharIndexValue << 18
else If ( n = 2 )
buffer += Base64CharIndexValue << 12
else If ( n = 3 )
buffer += Base64CharIndexValue << 6
else
{
buffer += Base64CharIndexValue
WriteToMemory(bin, buffer >> 16 & 255)
WriteToMemory(bin, buffer >> 8 & 255)
WriteToMemory(bin, buffer & 255)
}
}
sum := Base64CodeLength - binSize
if ( sum = 2 )
WriteToMemory(bin, buffer >> 16 & 255)
else if ( sum = 1 )
{
WriteToMemory(bin, buffer >> 16 & 255)
WriteToMemory(bin, buffer >> 8 & 255)
}
return binSize
}
Base64Code := "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgARCAACAAIDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAG/B//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQ8//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z"
pos := 0
Bytes := Base64Decode(Base64Code, bin)
File1 := FileOpen("test.jpg", "w")
File1.RawWrite(bin, Bytes)
File1.Close()
Re: Decoding Base64 image failed
Posted: 15 Dec 2018, 12:41
by hd0202
after dllcall check errorlevel and have a look at the help -> dllcall
Hubert
Re: Decoding Base64 image failed
Posted: 19 Dec 2018, 09:47
by afe
@hd0202 , thank you very much!
I used my code to test the script startup time much slower than using DllCall ("Crypt32.dll\CryptStringToBinary" for 2 seconds. Is the code quality affecting the speed?
Using DllCall ("Crypt32.dll\CryptStringToBinary"
AutoHotkey.exe - 1 executions
0.2129
AutoHotkey.exe - 1 executions
0.1838
AutoHotkey.exe - 1 executions
0.2254
AutoHotkey.exe - 1 executions
0.1962
AutoHotkey.exe - 1 executions
0.1921
My code
AutoHotkey.exe - 1 executions
1.8072
AutoHotkey.exe - 1 executions
1.8963
AutoHotkey.exe - 1 executions
1.9433
AutoHotkey.exe - 1 executions
1.8579
AutoHotkey.exe - 1 executions
1.8075