两个完全相同的.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 1
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 1
默认编码?
|
3
whoami9894 OP |
4
atuocn 2018-12-12 19:37:32 +08:00 1
utf8 编码只会在全部字符都在 ascii 码范围内,才和字节码能对上。
字符串也不能认为用 latin-1 编码就会变成 ascii 字节码。你试试 '中文'.decode('latin-1') 如果是新开发,要同时支持 py2, py3,建议统一用 utf8。如果是 py2 升级 py3,要保持旧接口的兼容性,改不了。那用楼主的主要语言环境的语言编码比如 gb2312,或者取系统的编码. |
5
CharAct3 2018-12-12 20:04:06 +08:00 3
@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
|