哈希算法Node js vs Python

哈希算法Node js vs Python,python,node.js,algorithm,hash,Python,Node.js,Algorithm,Hash,我试图将Python上编写的哈希算法转换为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

我试图将Python上编写的哈希算法转换为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

这里的日期值
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部分的东西


你能告诉我哪里出了问题吗。感谢您的帮助

您希望数据的散列与上面的Python代码相同吗? 如果没有,您可以在NodeJS中查看下面的Sha256模块


实际上,它已经调出了很多遗漏的部分

节点部分:
  • 新缓冲区('c5')

    不表示
    ,但表示

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

  • 新缓冲区(2)

    不表示
    ,它只分配2个字节

  • CLIENT\u ID+SECRET+y+m+d

    缓冲区的串联不是这样工作的

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

uuid部件:
  • 结果证明uuid操作修改版本的缓冲区(
    bytes\u le
    python代码中的一部分)
最有趣的部分是:
  • 在uuid的python版本中,如果没有将任何版本参数传递给
    uuid.uuid(…)
    ,uuid将生成一个没有固定位的ID

    根据RFC-4122 4.4 uuid

    这样,即使sha256哈希的结果相同,python和节点实现之间的结果仍然会有所不同

    python: 32d86f00-eb49-2739-e957-91513d2b9969
    node:   32d86f00-eb49-4739-a957-91513d2b9969
                          ^    ^
    
因此,我在这里看到了两种选择

  • 要将版本传递给python uuid(仅适用于最后一个uuid调用uuid.uuid(bytes_le=…,version=4)),python将以这种方式返回
    32d86f00-eb49-4739-a957-91513d2b9969
  • 如果在python项目中无法更改源代码,我想可以选择fork uuid并删除
    节点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”。替换(/-/g,”);
const secret_hex_str=“2cf26ff5-bd06-3245-becf-4d5a3baa704f”。替换(/-/g,”);
让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'));
设d=Buffer.from(到_字节(null,2,4));
设m=Buffer.from(到_字节(null,9,4));
设y=Buffer.from(到_字节(null,2017,4));
让data=Buffer.concat([CLIENT_ID,SECRET,y,m,d]);
让hashBytes=hash.update(数据'utf8').digest().slice(0,16);
hashBytes=[].slice.call(hashBytes,0);
hashBytes=Buffer.from(to_bytes_le(hashBytes));
let token=uuidv4({random:hashBytes});
console.log(令牌);
// https://stackoverflow.com/questions/16022556/has-python-3-to-bytes-been-back-ported-to-python-2-7
函数到字节(十六进制字符串、数字、长度、尾数){
if(hextstring==null&&number==null){
抛出新错误(“缺少十六进制字符串或数字”);
}
如果(!length | | isNaN(长度)){
抛出新错误(“缺少或无效字节数组长度编号”);
}
if(hexString&&typeof hexString!=“string”){
抛出新错误(“十六进制值的格式无效”);
}
if(hextstring==null){
如果(isNaN(编号)){
抛出新错误(“无效数字”);
}
hextstring=number.toString(16);
}
let byteArray=[];
如果(hexString.length%2!==0){
hexString='0'+hexString;
}
常量比特长度=长度*2
hexString=(“0”。重复(比特长度)+hexString。切片(-1*比特长度);
for(设i=0;i
nodejs代码中的
散列是什么?
在您使用它的地方:
hash.update
。很抱歉,我错过了
const hash=crypto.createHash('sha256')让我更新问题,这就是重点,否则我可以以数百万种方式生成哈希。python的现有哈希用于生成令牌,应该与nodejsok相同。如果有帮助的话,你可以看看这个。你做的那些事真是太棒了。我试过了,大部分都成功了,正如我所指出的,仍然存在差异。事实上,我在python上传递的版本号是
CLIENT_ID=uuid.uuid('C5F92E0D-E762-32CD-98CB-8C546C410DBE',version=4)SECRET=uuid.uuid('2CF26FF5-BD06-3245-BECF-4D5A3BAA704F',version=4)
但是它不起作用,并且给出了一个完全不同的散列。@AbhikChakraborty尝试仅为最后一个uuid调用应用版本参数
uuid.uuid(bytes_le=
它应该返回
32d86f00-eb49-4739-a957-91513d2b9969
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;
}