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