leevis.com
leevis.com copied to clipboard
go 的 UrlEncode
当我们在代码里面curl一个url的时候,有时候会遇到一些奇葩的设计,url里有中文需要对url进行编码。如果直接调用url.QueryEscape转码,http.Get()时候会报错"unsupported protocol scheme"。如果不转码那么又会报http status 400.
那么,该怎么转码呢?go里貌似也没有一个现成的函数供直接转url的参数的。那就需要我们自己封装一个:
func UrlEncode(u string) (string, error) {
uary := strings.SplitAfterN(u, "?", 2)
if len(uary) == 2 {
m, e := url.ParseQuery(uary[1])
if e != nil {
return "", e
}
uary[1] = m.Encode()
}
return strings.Join(uary, ""), nil
}
补充16进制解码函数和2进制解码函数
package main
import (
"encoding/hex"
"fmt"
"strconv"
"strings"
)
func hexDecode(str string) string {
s := strings.TrimPrefix(strings.TrimPrefix(str, "0x"), "0X")
data, err := hex.DecodeString(s)
if err != nil {
return str
}
return string(data)
}
func binDecode(str string) string {
var sb strings.Builder
bt := []byte(strings.TrimPrefix(strings.TrimPrefix(str, "0b"), "0B"))
l := len(bt)
sb.Grow(l + 7)
for b, e := 0, (l-1)%8+1; e <= l; e += 8 {
c, err := strconv.ParseUint(string(bt[b:e]), 2, 32)
if err != err {
return str
}
sb.WriteString(string(c))
b = e + 1
}
return sb.String()
}
func main() {
fmt.Println(binDecode("0b01100001") == "a")
fmt.Println(binDecode("0B01100001") == "a")
fmt.Println(binDecode("01100001") == "a")
fmt.Println(binDecode("0b1100001") == "a")
fmt.Println(binDecode("0B1100001") == "a")
fmt.Println(binDecode("1100001") == "a")
fmt.Println(hexDecode(binDecode("0b001100100110011000110010001100000011011000110010")) == "/ b")
fmt.Println(hexDecode(binDecode("0B001100100110011000110010001100000011011000110010")) == "/ b")
fmt.Println(hexDecode(binDecode("001100100110011000110010001100000011011000110010")) == "/ b")
fmt.Println(hexDecode(binDecode("0b01100100110011000110010001100000011011000110010")) == "/ b")
fmt.Println(hexDecode(binDecode("0B01100100110011000110010001100000011011000110010")) == "/ b")
fmt.Println(hexDecode(binDecode("01100100110011000110010001100000011011000110010")) == "/ b")
fmt.Println(hexDecode(binDecode("0b1100100110011000110010001100000011011000110010")) == "/ b")
fmt.Println(hexDecode(binDecode("0B1100100110011000110010001100000011011000110010")) == "/ b")
fmt.Println(hexDecode(binDecode("1100100110011000110010001100000011011000110010")) == "/ b")
}
优化2进制解码函数
func binDecode(str string) string {
var sb bytes.Buffer
bt := []byte(strings.TrimPrefix(strings.TrimPrefix(str, "0b"), "0B"))
l := len(bt)
sb.Grow(l + 7)
for b, e := 0, (l-1)%8+1; e <= l; e += 8 {
c, err := strconv.ParseUint(string(bt[b:e]), 2, 32)
if err != err {
return str
}
sb.WriteByte(byte(c))
b = e + 1
}
return sb.String()
}