Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[AHK_L unicode] URI encode (URL encode) function


  • Please log in to reply
3 replies to this topic
Flowerpiggy
  • Members
  • 45 posts
  • Last active: Dec 20 2012 02:57 PM
  • Joined: 22 Apr 2011
It's Lexicos's work. I did the easiest part: add % to the hexdecimal string:-)


;example
keyword := uri_encode("测试")
msgbox, An brower window will open searching for %keyword%.
run, https://www.google.com/#newwindow=1&q=%keyword%&fp=1&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&cad=b


;functions start
uri_encode(Unicode_string)
{
;converts unicode_string to uri enocoded string for autohotkey_l unicode version	
;http://www.autohotkey.com/forum/viewtopic.php?t=71619

UTF16 := Unicode_string

n := StrPutVar(UTF16, UTF8, "UTF-8")
raw_hex := MCode_Bin2Hex(&UTF8, n-1)
i := strlen(raw_hex)/2

loop, %i%
	{
	frag := "%" . substr(raw_hex, a_index*2-1,2)
	r_s .= frag
	}
return r_s

}



MCode_Bin2Hex(addr, len) {
    Static fun
    If (fun = "") {
        If Not A_IsUnicode
        h=
        ( LTrim Join
            8B54240C85D2568B7424087E3A53578B7C24148A07478AC8C0E90480F9090F97C3F6
            DB80E30702D980C330240F881E463C090F97C1F6D980E10702C880C130880E464A75
            CE5F5BC606005EC3
        )
        Else
        h=
        ( LTrim Join
            8B44240C8B4C240485C07E53568B74240C578BF88A168AC2C0E804463C090FB6C076
            066683C037EB046683C03066890180E20F83C10280FA09760C0FB6D26683C2376689
            11EB0A0FB6C26683C03066890183C1024F75BD33D25F6689115EC333C0668901C3
        )
        VarSetCapacity(fun, n := StrLen(h)//2)
        Loop % n
            NumPut("0x" . SubStr(h, 2 * A_Index - 1, 2), fun, A_Index - 1, "Char")
    }
    VarSetCapacity(hex, A_IsUnicode ? 4 * len + 2 : 2 * len + 1)
    DllCall(&fun, "uint", &hex, "uint", addr, "uint", len, "cdecl")
    VarSetCapacity(hex, -1) ;update StrLen
    Return hex
}

StrPutVar(string, ByRef var, encoding)
{
    VarSetCapacity( var, StrPut(string, encoding)
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    return StrPut(string, &var, encoding)
}
	



imGuest
  • Guests
  • Last active:
  • Joined: --
I use these UriEncode/UriDecode functions.
tested in AHKL Ansi/Unicode.

; modified from jackieku's code (http://www.autohotkey.com/forum/post-310959.html#310959)
UriEncode(Uri, Enc = "UTF-8")
{
	StrPutVar(Uri, Var, Enc)
	f := A_FormatInteger
	SetFormat, IntegerFast, H
	Loop
	{
		Code := NumGet(Var, A_Index - 1, "UChar")
		If (!Code)
			Break
		If (Code >= 0x30 && Code <= 0x39 ; 0-9
			|| Code >= 0x41 && Code <= 0x5A ; A-Z
			|| Code >= 0x61 && Code <= 0x7A) ; a-z
			Res .= Chr(Code)
		Else
			Res .= "%" . SubStr(Code + 0x100, -1)
	}
	SetFormat, IntegerFast, %f%
	Return, Res
}

UriDecode(Uri, Enc = "UTF-8")
{
	Pos := 1
	Loop
	{
		Pos := RegExMatch(Uri, "i)(?:%[\da-f]{2})+", Code, Pos++)
		If (Pos = 0)
			Break
		VarSetCapacity(Var, StrLen(Code) // 3, 0)
		StringTrimLeft, Code, Code, 1
		Loop, Parse, Code, `%
			NumPut("0x" . A_LoopField, Var, A_Index - 1, "UChar")
		StringReplace, Uri, Uri, `%%Code%, % StrGet(&Var, Enc), All
	}
	Return, Uri
}

StrPutVar(Str, ByRef Var, Enc = "")
{
	Len := StrPut(Str, Enc) * (Enc = "UTF-16" || Enc = "CP1200" ? 2 : 1)
	VarSetCapacity(Var, Len, 0)
	Return, StrPut(Str, &Var, Enc)
}


Flowerpiggy
  • Members
  • 45 posts
  • Last active: Dec 20 2012 02:57 PM
  • Joined: 22 Apr 2011
I think yours is possibly better as it only uses the build-in functions.

I don't understand how exactly strput, numget and numput works:-) It amazes how much autohotkey can do. Can anyone explain a little bit?

For example, the unicode of this Korean character "유" is C720, and the utf-8 code is EC9CA0

Unicode Binary: 11000111 00100000
utf-8 Binary: 11101100 10011100 10100000

So the utf-8 format is:

1110xxxx 10xxxxxx 10xxxxxx

And xxxx is to be filled with the original unicode binary.

I would like to know what exactly StrPutVar do?

StrPutVar(Uri, Var, Enc)

And why do we need to +0x100 here?

SubStr(Code + 0x100, -1)

I trying to learn how memory works so if any one can shed a light, I will be very grateful.

OtherGuest
  • Guests
  • Last active:
  • Joined: --
it will be simple if using the COM included in AutoHotkey_L. try this one.

UriEncode(Uri)
{
    oSC := ComObjCreate("ScriptControl")
    oSC.Language := "JScript"
    Script := "var Encoded = encodeURIComponent(""" . Uri . """)"
    oSC.ExecuteStatement(Script)
    Return, oSC.Eval("Encoded")
}

UriDecode(Uri)
{
    oSC := ComObjCreate("ScriptControl")
    oSC.Language := "JScript"
    Script := "var Decoded = decodeURIComponent(""" . Uri . """)"
    oSC.ExecuteStatement(Script)
    Return, oSC.Eval("Decoded")
}