urlencode 编码同一段字符, Python 和 Java 出来的结果不一样 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
vileer
V2EX    Python

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

  •  
  •   vileer 2018-05-19 20:02:22 +08:00 5013 次点击
    这是一个创建于 2709 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我从文件里面读取一个 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 的结果这个要怎么做呢?

    第 1 条附言    2018-05-21 15:04:14 +08:00
    首先谢谢各位热心的解答,问题解决了,原因如二楼 @imn1 所说 python 默认的编码是 latin-1,java 是 utf-8,在 java 上将从文件上读出来的字节数组用 new String(byte[],"Latin1")转成 String,然后 urlencode 的时候也指定 Latin1 的编码就行了,关于很多人说到的为什么要放到 json 的问题,其实是我说错了,在 python 里面应该是 dictionary 才对。再次感谢大家的热心帮助,仅以不多的铜币感谢回答的各位。
    13 条回复    2018-05-21 15:05:27 +08:00
    ebingtel
        1
    ebingtel  
       2018-05-19 20:24:49 +08:00   1
    ……先 base64 encode 再 urlencode ;
    imn1
        2
    imn1  
       2018-05-19 20:48:03 +08:00   2
    编码问题
    python 在 latin-1/gbk 下执行
    java 在 utf-8 下执行

    字符'',它的 ASCII/Latin-1 为 AC,utf-8(bytes)是 C2AC
    flyingghost
        3
    flyingghost  
       2018-05-20 00:18:33 +08:00   1
    塞到 json 里用 urlencode 首先就错了。base64 足矣。
    其次,问题的原因是编码。如 2 楼所言。
    flyingghost
        4
    flyingghost  
       2018-05-20 00:30:04 +08:00   1
    你要这么想:输入是 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
        5
    Arnie97  
       2018-05-20 00:40:58 +08:00 via Android   2
    实际上 urlencode 暗含了两个步骤:
    将 str 编码为 bytes,这一步的编码存在分别 ;
    将 bytes 编码为 hex,这一步都是相同的。

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

    同理,Python 中建议使用 encoding= 关键字参数来指明字符编码,否则会随系统环境设置而变化。
    1daydayde
        6
    1daydayde  
       2018-05-20 09:03:24 +08:00 via iPhone   1
    是不是有一个默认 safe encode
    sutra
        7
    sutra  
       2018-05-20 15:01:00 +08:00   1
    geelaw
        8
    geelaw  
       2018-05-20 15:04:53 +08:00   1
    wave 文件不总是可以被理解为一个字符串,这个做法一开始就错了。
    sutra
        9
    sutra  
       2018-05-20 15:47:57 +08:00   1
    @geelaw 当作 bytes 读进来,然后 encode 成 string,再 urlencode。
    vileer
        10
    vileer  
    OP
       2018-05-20 18:37:03 +08:00
    @flyingghost 其实应该是 post 的一个参数所以 urlencode 了
    vileer
        11
    vileer  
    OP
       2018-05-20 18:39:15 +08:00
    @geelaw 确实是不合理的设计,不过对方的服务器 API 设计成这样也没办法
    msg7086
        12
    msg7086  
       2018-05-21 02:33:31 +08:00   1
    POST 的参数和 JSON 没关系吧?
    POST 的参数在 POST 的时候做转码,为何要先转码写入 JSON ?
    vileer
        13
    vileer  
    OP
       2018-05-21 15:05:27 +08:00
    @msg7086 确实没关系,我看错了,post 参数是放在 dictionary 里面,只是这写法像 json。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     897 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 22:42 PVG 06:42 LAX 15:42 JFK 18:42
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86