urlencode 编码同一段字符, Python 和 Java 出来的结果不一样

2018-05-19 20:02:22 +08:00
 vileer

我从文件里面读取一个 wav 文件然后,通过 urlencode 塞到 json 里面去,python 的 urllib.urlencode()出来的结果如下:

RIFF%AC%89%03%00WAVEfmt+

但是用 java 的 UrlEncoder 去编码结果却变成下面这样:

RIFF%C2%AC%C2%89%03%00WAVEfmt+

明显的 java 的 UrlEncoder 在 0xAC 和 0x89 这两个特殊字符前加上了%C2 这个字符,如果我想要用 java 得到 python 的结果这个要怎么做呢?

4492 次点击
所在节点    Python
13 条回复
ebingtel
2018-05-19 20:24:49 +08:00
……先 base64 encode 再 urlencode ;
imn1
2018-05-19 20:48:03 +08:00
编码问题
python 在 latin-1/gbk 下执行
java 在 utf-8 下执行

字符'¬',它的 ASCII/Latin-1 为 AC,utf-8(bytes)是 C2AC
flyingghost
2018-05-20 00:18:33 +08:00
塞到 json 里用 urlencode 首先就错了。base64 足矣。
其次,问题的原因是编码。如 2 楼所言。
flyingghost
2018-05-20 00:30:04 +08:00
你要这么想:输入是 bin,要求输出是 string,用什么?当然用 base64 一步达成。
urlencode 输出是 string,但输入也是 string,并不符合你的场景需求,你还得为它做一步转换准备好入参。预先从 bin -> string 过程中,必然会引入新的因素:编码。
再说一下字符编码。并不是任意一个 bin 都能转成对应的 string 的。很多编码方式都有它自己的规则,例如 utf-8,对于 n 字节的符号( n > 1 ),第一个字节的前 n 位都设为 1,第 n + 1 位设为 0,后面字节的前两位一律设为 10。因此很容易构造(遭遇)一个非法的 bin 序列在转换时报错。还有,转换后的码点是不是一个合法字符?这是由码表说了算。码表上不存在的,有可能就作为非法字符忽略或者显示为框或者问号。
假设第一步转换凑巧没出错,还得考虑第一步转出特殊字符,第二步 urlencode 时会不会正常处理。例如\0、\r、\n。。。毕竟它的设计并不是计划用在这种场合。
Arnie97
2018-05-20 00:40:58 +08:00
实际上 urlencode 暗含了两个步骤:
将 str 编码为 bytes,这一步的编码存在分别 ;
将 bytes 编码为 hex,这一步都是相同的。

在 Java 中,建议用 URLEncoder.encode(str, encoding)来明确的指出选择了哪种字符编码,以免踩坑。而 URLEncoder.encode(str) 已经是官方不建议使用的写法,如果用的是 IntelliJ IDEA 这么写会受到警告。

同理,Python 中建议使用 encoding= 关键字参数来指明字符编码,否则会随系统环境设置而变化。
0312birdzhang
2018-05-20 09:03:24 +08:00
是不是有一个默认 safe encode
sutra
2018-05-20 15:01:00 +08:00
geelaw
2018-05-20 15:04:53 +08:00
wave 文件不总是可以被理解为一个字符串,这个做法一开始就错了。
sutra
2018-05-20 15:47:57 +08:00
@geelaw 当作 bytes 读进来,然后 encode 成 string,再 urlencode。
vileer
2018-05-20 18:37:03 +08:00
@flyingghost 其实应该是 post 的一个参数所以 urlencode 了
vileer
2018-05-20 18:39:15 +08:00
@geelaw 确实是不合理的设计,不过对方的服务器 API 设计成这样也没办法
msg7086
2018-05-21 02:33:31 +08:00
POST 的参数和 JSON 没关系吧?
POST 的参数在 POST 的时候做转码,为何要先转码写入 JSON ?
vileer
2018-05-21 15:05:27 +08:00
@msg7086 确实没关系,我看错了,post 参数是放在 dictionary 里面,只是这写法像 json。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/456179

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX