哈希algorithm节点js与Python

我正试图将一个在Python上编写的哈希algorithm转换为node.js

Python代码看起来像

import uuid import hashlib import struct CLIENT_ID = uuid.UUID('c5f92e0d-e762-32cd-98cb-8c546c410dbe') SECRET = uuid.UUID('2cf26ff5-bd06-3245-becf-4d5a3baa704f') data = CLIENT_ID.bytes_le + SECRET.bytes_le + struct.pack("I", 2017) + struct.pack("I", 9) + struct.pack("I", 2) token = str(uuid.UUID(bytes_le=hashlib.sha256(data).digest()[0:16])) 

生成的令牌是32d86f00-eb49-2739-e957-91513d2b9969

这里的date值struct.pack值是使用datetime时间生成的,但为了方便,我在这里硬编码。

我试图通过查看相应的库的python文档转换相同,做到目前为止

 let CLIENT_ID = new Buffer('c5f92e0d-e762-32cd-98cb-8c546c410dbe'); let SECRET = new Buffer('2cf26ff5-bd06-3245-becf-4d5a3baa704f'); let d = new Buffer(2); let m = new Buffer(9); let y = new Buffer(2017); let data = CLIENT_ID+SECRET+y+m+d; const uuidv4 = require('uuid/v4'); const hash = crypto.createHash('sha256'); let token = uuidv4({random: hash.update(data, 'utf8').digest().slice(0, 16)}, 0); 

而它产生的散列是b7b82474-eab4-4295-8318-cc258577ff9b

所以,基本上我很遗憾地忽略了nodejs部分。

你能指导我哪里出了问题。 谢谢您的帮助

实际上它有很多错过的部分。

节点部分:

  • new Buffer('c5')

    不代表<Buffer c5> ,但<Buffer 63 35>

    要编写c5,您需要使用Buffer.from([0xc5])Buffer.from([197]) (dec)。

  • new Buffer(2)

    不代表<Buffer 02> ,它只分配2个字节。

  • CLIENT_ID+SECRET+y+m+d

    缓冲区的连接不以这种方式工作。

    使用数组缓冲区和Buffer.concat([buffers])来连接缓冲区。

uuid部分:

  • 事实certificate,uuid操作缓冲区的修改版本(在Python代码中的bytes_le部分)

最有趣的部分:

  • 在uuid的python版本中,如果没有版本参数被传递给uuid.UUID(...) ,uuid会生成一个ID而不固定位

    根据RFC-4122 4.4 uuid 应该修复这些位 。

    uuid.py跳过RFC-4122 4.4

    node-uuid / v4.js修复了所需的位

    即使sha256散列的结果相同,python和node之间的结果仍然会有所不同

     python: 32d86f00-eb49-2739-e957-91513d2b9969 node: 32d86f00-eb49-4739-a957-91513d2b9969 ^ ^ 

所以,我在这里看到2个选项

  • 将版本传递给python uuid(仅用于最后的uuid调用uuid.UUID(bytes_le = …,version = 4)),那样python会返回32d86f00-eb49-4739-a957-91513d2b9969
  • 如果没有办法在Python项目中更改源代码,我想有一个选项可以fork uuid并在node-uuid/v4.js删除两行代码?

请参阅下面的代码节点版本:

 const uuidv4 = require('uuid/v4'); const crypto = require('crypto'); const hash = crypto.createHash('sha256'); const client_id_hex_str = "c5f92e0d-e762-32cd-98cb-8c546c410dbe".replace(/-/g, ""); const secret_hex_str = "2cf26ff5-bd06-3245-becf-4d5a3baa704f".replace(/-/g, ""); let CLIENT_ID = Buffer.from(to_bytes_le(to_bytes(client_id_hex_str, null, 16, 'big'))); let SECRET = Buffer.from(to_bytes_le(to_bytes(secret_hex_str, null, 16, 'big'))); let d = Buffer.from(to_bytes(null, 2, 4)); let m = Buffer.from(to_bytes(null, 9, 4)); let y = Buffer.from(to_bytes(null, 2017, 4)); let data = Buffer.concat([CLIENT_ID, SECRET, y, m, d]); let hashBytes = hash.update(data, 'utf8').digest().slice(0, 16); hashBytes = [].slice.call(hashBytes, 0); hashBytes = Buffer.from(to_bytes_le(hashBytes)); let token = uuidv4({random: hashBytes}); console.log(token); // https://stackoverflow.com/questions/16022556/has-python-3-to-bytes-been-back-ported-to-python-2-7 function to_bytes(hexString, number, length, endianess) { if (hexString == null && number == null) { throw new Error("Missing hex string or number."); } if (!length || isNaN(length)) { throw new Error("Missing or invalid bytes array length number."); } if (hexString && typeof hexString != "string") { throw new Error("Invalid format for hex value."); } if (hexString == null) { if (isNaN(number)) { throw new Error("Invalid number."); } hexString = number.toString(16); } let byteArray = []; if (hexString.length % 2 !== 0) { hexString = '0' + hexString; } const bitsLength = length * 2 hexString = ("0".repeat(bitsLength) + hexString).slice(-1 * bitsLength); for (let i = 0; i < hexString.length; i += 2) { const byte = hexString[i] + hexString[i + 1]; byteArray.push(parseInt(byte, 16)); } if (endianess !== "big") { byteArray = byteArray.reverse(); } return byteArray; } // https://github.com/python/cpython/blob/master/Lib/uuid.py#L258 function to_bytes_le(bytes) { const p1 = bytes.slice(0, 4).reverse(); const p2 = bytes.slice(4, 6).reverse(); const p3 = bytes.slice(6, 8).reverse(); const p4 = bytes.slice(8); const bytes_le = [].concat.apply([], [p1, p2, p3, p4]); return bytes_le; } 

你想要数据的哈希与上面的Python代码相同吗? 如果没有,你可以看一下NodeJS下面的Sha256模块

https://www.npmjs.com/package/sha256