Эквивалент MD5 от CryptoJS и Python Hashlib

Я пытаюсь перенести некоторый код из JS в Python. Я застрял с этим кодом в JS:

const crypto = require('crypto')

var txtToHash = "Hello¤World¤";
var md5sum = crypto.createHash('md5');
md5sum.update(new Buffer(txtToHash, 'binary'));
md5val = md5sum.digest('hex');
// equivalent to
// crypto.createHash('md5').update(urlPart, 'binary').digest('hex'));

Возвращает: 3a091f847ee21c7c1927c19e0f29a28b

И в Python 3.7 у меня есть этот код:

import hashlib

txtToHash = "Hello¤World¤"
md5val = hashlib.md5(txtToHash.encode()).hexdigest() 

Возвращает: f0aef2e2e25ddf71473aa148b191dd70

Пожалуйста, почему они разные? Я не могу найти ответ в Google или SO.


person djawed    schedule 24.09.2018    source источник


Ответы (1)


вы используете две разные кодировки символов при создании дайджеста.

Убедитесь, что у вас тот же тип кодировки символов. ваша реализация node js использует кодировку «двоичного» псевдонима «latin1». Где в коде на питоне используется кодировка символов UTf8.

Когда вы указали txtToHash.encode() , это означает, что кодируете текст в utf-8.

Поэтому измените создание дайджеста, чтобы оно соответствовало кодировке символов, одинаковой в обеих средах.

либо измените свой код nodejs

md5sum.update(new Buffer(txtToHash, 'utf8'));

или измените свой код Python на

md5val = hashlib.md5(txtToHash.encode('latin1')).hexdigest()

приведенное выше должно дать тот же результат >> 3a091f847ee21c7c1927c19e0f29a28b

Примечание. Хотя код python дает желаемый результат. Я бы не советовал этого, потому что кодировка latin1 имеет лишь небольшое подмножество символов по сравнению с utf8. Поэтому я рекомендую вам изменить кодировку на utf-8 в вашем приложении node js и применить ту же кодировку в python.

person karthick    schedule 24.09.2018
comment
Я не могу изменить код JS. Я должен перенести его на Python. Я не понимаю, почему txtToHash.encode() не эквивалентно new Buffer(txtToHash, 'binary'). Как я могу преобразовать txtToHash в байты (двоичные)? - person djawed; 24.09.2018
comment
это точно не то же самое. то, что вы делаете в python, просто применяет кодировку символов к UTF8. В то время как в узле вы создаете буфер без кодировки UTF-8. поэтому они имеют разную кодировку символов, когда код доходит до создания дайджеста - person karthick; 24.09.2018
comment
Итак, как я могу написать это на Python, пожалуйста? - person djawed; 24.09.2018
comment
Это работает! Большое спасибо :) Но почему это работает с latin1, а не с utf-8? - person djawed; 25.09.2018
comment
@djawed: вы используете «двоичную» кодировку в своем приложении nodejs. 'binary' - это псевдоним для 'latin1'. nodejs.org/api/buffer.html - person karthick; 25.09.2018
comment
Не знал этого. Большое спасибо. Надеюсь, это поможет другим. - person djawed; 25.09.2018