You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang中如何判断未知来源字符串是否经过URL编码

Go语言判断字符串是否为URL编码并安全解码

核心判断思路

URL编码(百分号编码)的判定不能仅靠字符串中是否存在%字符,也不能仅靠解码不报错作为依据——普通字符串也可能包含%,且无转义字符的普通字符串传入URL解码函数也不会报错、会直接返回原串。
正确判定需要同时满足两个条件:

  • 字符串中存在合法的URL转义序列:即%后紧跟2位十六进制字符(取值范围为0-9/a-f/A-F)
  • 对字符串执行URL解码操作无报错,且解码结果与原字符串不相等

修正补全后的代码

package main

import (
	"fmt"
	"log"
	"net/url"
)

// decode 执行URL Query解码
func decode(str1 string) string {
	resl, err := url.QueryUnescape(str1)
	if err != nil {
		log.Printf("URL decode error: %v", err)
		return str1
	}
	return resl
}

// ifUrlEncoded 判断字符串是否为URL编码格式
func ifUrlEncoded(s string) bool {
	hasValidEscape := false
	length := len(s)
	for i := 0; i < length; i++ {
		// 找到%字符,校验后面是否跟2位合法十六进制字符
		if s[i] == '%' {
			if i+2 >= length {
				// %后面不足2位,不是合法转义
				continue
			}
			c1, c2 := s[i+1], s[i+2]
			isHex := func(c byte) bool {
				return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')
			}
			if isHex(c1) && isHex(c2) {
				hasValidEscape = true
				break
			}
		}
	}
	if !hasValidEscape {
		return false
	}
	// 二次验证:解码无报错且结果和原串不同
	decoded, err := url.QueryUnescape(s)
	if err != nil {
		return false
	}
	return decoded != s
}

func main() {
	testStrs := []string{
		"elementINPUT61599119%5B%5D", // 合法URL编码
		"普通测试字符串",                // 普通中文串
		"test%GGstring",              // 带非法%序列,不算编码
		"test123",                    // 普通英文串
		"100%测试",                    // 带%但无合法转义
	}
	for _, str := range testStrs {
		if ifUrlEncoded(str) {
			fmt.Printf("原串: %s -> 解码结果: %s\n", str, decode(str))
		} else {
			fmt.Printf("原串: %s -> 普通字符串,无需解码: %s\n", str, str)
		}
	}
}

逻辑说明

  • 先做轻量遍历校验,避免对完全没有转义特征的字符串做不必要的解码操作,性能更好
  • 过滤掉%后面字符不符合十六进制规则的场景,避免把普通带%的字符串误判为URL编码
  • 解码后对比原串,避免把本身不需要解码、解码后和原串完全一致的字符串误判

内容的提问来源于stack exchange,提问作者Mesc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 08:39:29