Функция hexEncode
берет строку и преобразует ее в последовательность шестнадцатеричных представлений составляющих байтов своего кодированного представления UTF8. Эквивалентом в Python является кодирование входной строки Unicode в UTF-8, а затем перекодирование результата этого в hex , например,
>>> import binascii
>>> binascii.hexlify('d'.encode('utf-8'))
b'64'
>>> binascii.hexlify('¡¢£¤¥'.encode('utf-8'))
b'c2a1c2a2c2a3c2a4c2a5'
Примечание: в Python 2.7 это будет -
>>> 'd'.encode('utf-8').encode('hex')
'64'
>>> u'¡¢£¤¥'.encode('utf-8').encode('hex')
'c2a1c2a2c2a3c2a4c2a5'
Если вы проверите это с помощью примера пароля, он должен вывести тот же результат, что и для веб-сайта, с одним предупреждением.
hexEncode('d')
"64000000"
Обратите внимание, что Javascript добавляет количество конечных 0, делая длину строки кратной 8. Нам нужно дополнить результат, чтобы получить тот же результат.
>>> s = binascii.hexlify('d'.encode('utf-8'))
>>> n = len(s)
>>> from math import ceil
>>> next_8_multiple = int(ceil(n/8.0) * 8)
>>> s.ljust(next_8_multiple, b'0')
b'6400000000'
Мы можем завершить это в полной функции:
from math import ceil
import binascii
def hex_encode_and_pad(s):
hex = binascii.hexlify(s.encode('utf-8'))
n = len(hex)
next_8_multiple = int(ceil(n/8.0) * 8)
zeros_to_append = next_8_multiple - n
return hex.ljust(next_8_multiple, b'0')
Теперь это дает тот же результат, что и для функции Javascript:
>>> hex_encode_and_pad('d')
'64000000'
Следующим шагом будет завернуть его в строковое представление JSON. Вы можете сделать это вручную, закодировав строку + просто интерполировав токен, например,
value = '{"TokenId":"%s","Password":""}' % token
Или путем создания строки JSON из словаря Python -
import json
data = {'TokenId': token, 'Password': ''}
value = json.dumps(data)
Полный код, основанный на приведенном выше примере запроса, будет выглядеть так:
import binascii
import json
from math import ceil
from requests import session
def hex_encode_and_pad(s):
hex = binascii.hexlify(s.encode('utf-8'))
n = len(hex)
next_8_multiple = int(ceil(n/8.0) * 8)
zeros_to_append = next_8_multiple - n
return hex.ljust(next_8_multiple, b'0')
with session() as s:
password = u'your_password'
token = hex_encode_and_pad(password)
data = {'TokenId': token, 'Password': ''}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
payload = {
'USER': 'username',
'PASSWORD': json.dumps(data),
'TARGET': 'https://www.THISSITE.com/pg'
}
resp = s.post('https://www.THISSITE.com/THIS/fcc/THISSITE.fcc', headers=headers, data=payload )
html = resp.text
print(html)