进制君在线工具合集

16进制转url编码:一眼看懂编码差异

抓包或看日志时,常会遇到一串形如 %E4%B8%AD 的字符,或者一段十六进制字节。很多人第一反应是「这俩是不是一回事」。16进制转url编码,本质是把字节的十六进制表示还原成URL里可传输的百分号形式,或者反过来把百分号编码拆成十六进制字节来核对。搞清这层关系,排查乱码、签名不一致、参数被截断这类问题时,心里就有底了。

先分清:十六进制字节和百分号编码不是两个世界

十六进制是数字的一种写法,一个字节通常写成两位,比如 E4、B8、AD。URL编码则是把不能直接出现在地址里的字节,前面加个百分号再跟两位十六进制。所以 %E4%B8%AD 拆开看就是三个字节 E4 B8 AD,它们按UTF-8解释恰好是「中」字。

不少人把「16进制转url编码」理解成某种进制换算,其实中间没有算术运算,只是表示形式的切换:一边是连续的十六进制串,一边是带百分号分隔的串。真正要留意的,是这段字节该按哪种字符集解释。同一串字节用UTF-8和GBK读出来,结果可能完全不同。

什么时候会真的用到这种转换

做接口联调时,签名串里常混着百分号编码,而日志工具又习惯把原始字节打成十六进制,两边对不上就得手动还原。再比如从浏览器地址栏复制一段带中文的查询参数,粘到代码里之前,先看看它到底是已编码还是原样,能省掉重复编码的坑。

还有一种场景是排查「参数看起来对、服务端却收错」的问题。把请求里的百分号串拆成十六进制字节,再和预期字符串的字节逐位比对,往往能发现多了一个空格、少了一个换行,或者某个符号被编码成了别的形式。这种对照比盯着两串乱码猜要可靠得多。

转换时容易踩的几个坑

第一个坑是大小写。十六进制里的字母用大写还是小写,不同工具输出不一致,而某些签名校验对大小写敏感。转换前先确认目标环境的要求,别想当然。

第二个坑是保留字符。像斜杠、问号、井号、与号这些在URL里有语法含义的符号,编码与否会改变解析结果。把十六进制字节还原成百分号形式时,要判断这个字节原本是不是保留字符,不能一律编码或一律放过。

第三个坑是空格。空格在URL里可以写成加号,也可以写成百分号加两位十六进制,两种写法在不同上下文中含义有别。看到加号时别急着当成普通字符,先想想它是不是空格的替身。

第四个坑是重复编码。一段已经编码的串再转一次,百分号本身会被编码成 %25,结果越滚越长。转换前先判断输入是否已经处于编码状态,比事后反复调试省事。

动手转换时的稳妥做法

先确定字符集,再动手。中文内容在多数现代场景下按UTF-8处理,但老系统、老接口仍可能用别的编码,拿不准就两边都试一下,看哪边能还原出可读文本。

接着把输入规整成统一的字节序列:去掉多余的分隔符和空白,把连续的十六进制串按两位一组切开,确认每组都是合法字节。然后逐个字节判断是否需要百分号包裹,保留字符按上下文决定去留。最后把结果拼回去,用一次解码验证能否还原,能还原就说明转换方向没弄反。

如果只是核对而不是改写,可以只做单向观察:把百分号串拆成字节列表,和预期值并排看。这样不动原始数据,排查起来更安全。

总结

16进制转url编码说到底是字节表示形式的切换,不是数值运算。抓住字符集、保留字符、大小写和重复编码这几个关键点,转换和排查都会顺很多。遇到对不上的情况,先拆字节再比对,比盯着乱码猜更有效。

相关文章

常见问题

Q1十六进制串和百分号编码能直接互相替换吗?

在字节层面可以,但要保证字符集一致、保留字符处理一致。直接做字符串替换容易在大小写和分隔符上出错,稳妥的方式是先拆成字节再重组。

Q2为什么同一段中文转出来的结果不一样?

多半是字符集不同。UTF-8下一个汉字通常占多个字节,其他编码的字节数可能不同,转出来的十六进制串自然对不上。先统一字符集再比较。

Q3转换后出现 %25 是怎么回事?

说明输入里本来就有百分号,或者对已编码的内容又编码了一次。百分号被当作普通字符处理时就会变成 %25,检查一下是否重复编码即可。

Q4空格应该转成加号还是百分号形式?

取决于使用场景。查询字符串里加号常被当作空格,但路径部分不一定这么解释。拿不准时用百分号形式更稳妥,语义更明确。

Q5转换结果看着对,服务端却报错,查哪里?

先核对字符集,再检查保留字符是否被误编码,最后看有没有多余空白或大小写差异。逐字节比对原始请求和预期值,通常能定位到具体位置。