两个完全相同的.py
,分别是 2 和 3:
# py2 import base64 c = base64.b64decode('U/osUbnY8nSrWz4WPwKSwWPzKq9tOIQ9eCWnN5E+') plain = '{"name":"guest","admin":false}' res = '' for i in range(len(c)): res += chr(ord(c[i]) ^ ord(plain[i])) need = '{"name":"guest","admin":true}' payload = '' for i in range(len(need)): print ord(need[i]) ^ ord(res[i]) payload += chr(ord(need[i]) ^ ord(res[i])) print payload, len(payload) payload = base64.b64encode(payload) print payload # py3 import base64 c = base64.b64decode('U/osUbnY8nSrWz4WPwKSwWPzKq9tOIQ9eCWnN5E+') plain = '{"name":"guest","admin":false}' res = "" for i in range(len(c)): res += chr(c[i] ^ ord(plain[i])) need = '{"name":"guest","admin":true}' payload = "" for i in range(len(need)): print(ord(need[i]) ^ ord(res[i])) payload += chr(ord(need[i]) ^ ord(res[i])) print(payload, len(payload)) payload = base64.b64encode(payload.encode("utf-8")) print(payload)
输出结果,逐字节打印 ascii 码,payload 变量是完全相同的,但编码结果不同
# py2 83 250 44 81 185 216 242 116 171 91 62 22 63 2 146 193 99 243 42 175 109 56 132 61 106 54 190 33 137 S?Q 关 c? U/osUbnY8nSrWz4WPwKSwWPzKq9tOIQ9aja+IYk= # py3 83 250 44 81 185 216 242 116 171 91 62 22 63 2 146 193 99 243 42 175 109 56 132 61 106 54 190 33 137 Sú,Qòt[>■?=j6! b'U8O6LFHCucOYw7J0wqtbPhY/AsKSw4Fjw7Mqwq9tOMKEPWo2wr4hwok='
将两个 base64 字串放到 Python3 中解码:
>>> b64decode("U/osUbnY8nSrWz4WPwKSwWPzKq9tOIQ9aja+IYk=") b'S\xfa,Q\xb9\xd8\xf2t\xab[>\x16?\x02\x92\xc1c\xf3*\xafm8\x84=j6\xbe!\x89' >>> b64decode("U8O6LFHCucOYw7J0wqtbPhY/AsKSw4Fjw7Mqwq9tOMKEPWo2wr4hwok=") b'S\xc3\xba,Q\xc2\xb9\xc3\x98\xc3\xb2t\xc2\xab[>\x16?\x02\xc2\x92\xc3\x81c\xc3\xb3*\xc2\xafm8\xc2\x84=j6\xc2\xbe!\xc2\x89'
对于这种情况应该如何避免
![]() | 1 chenstack 2018-12-12 18:54:14 +08:00 ![]() python3 的那部分倒数第二行 payload = base64.b64encode(payload.encode("utf-8")) 改成 payload = base64.b64encode(payload.encode("latin-1")) 结果就和 python2 的一致了 |
![]() | 2 jingniao 2018-12-12 18:56:53 +08:00 via Android ![]() 默认编码? |
![]() | 3 whoami9894 OP |
4 atuocn 2018-12-12 19:37:32 +08:00 ![]() utf8 编码只会在全部字符都在 ascii 码范围内,才和字节码能对上。 字符串也不能认为用 latin-1 编码就会变成 ascii 字节码。你试试 '中文'.decode('latin-1') 如果是新开发,要同时支持 py2, py3,建议统一用 utf8。如果是 py2 升级 py3,要保持旧接口的兼容性,改不了。那用楼主的主要语言环境的语言编码比如 ,或者取系统的编码. |
![]() | 5 CharAct3 2018-12-12 20:04:06 +08:00 ![]() @whoami9894 不是的,Python2 中所谓的字符串其实就是 bytes。 在两段代码中 base64 编码 payload 的时候,传入的 bytes 是不一样的,所以结果不同。 举个例子,虽然在 Python2 和 Python3 中 '\xef' 看起来是一样的,但是在 Python2 中这就是一个 0xef 的 byte,而在 Python3 中则代表 U+00ef 这个 Unicode 字符,使用 utf-8 编码后就是 b'\xc3\xaf' 这个 bytes。 可以在 Python3 中试一试: '\xef' == '\u00ef' 想把 U+0080 到 U+00ff 的 Unicode 字符编码为对应的 0x80 到 0xff 的 byte,就要使用 latin-1 编码,这个不受语言的影响。 |
![]() | 6 whoami9894 OP |
![]() | 7 hacker 2018-12-13 03:23:16 +08:00 via iPhone 建议不要再用 Python 2.x |