Node.js哈希字符串?

493

我有一个字符串需要进行哈希处理,在node.js中,最简单的生成哈希的方法是什么?

这个哈希是用于版本控制而非安全性。


1
http://nodejs.org/api/crypto.html - zloctb
14个回答

966

如果你只想对简单字符串进行 MD5 哈希,我发现以下代码适用。

var crypto = require('crypto');
var name = 'braitsch';
var hash = crypto.createHash('md5').update(name).digest('hex');
console.log(hash); // 9b74c9897bac770ffc029102a200c5de

244
如果你执行require('crypto').createHash('md5').update(STRING_TO_BE_HASHED).digest("hex"),将得到一行代码。干杯,伙计! - balupton
3
在使用.update多次时(https://github.com/joyent/node/issues/749),我遇到了一些问题,当尝试使用`timbooo`的解决方案时,使用这个一行代码修复了它(因为哈希对象每次都会重新创建)。 - Max
1
有没有办法改变字符串的长度?不仅限于32个字符,可以是64、128或其他数字。 - Mikel
5
它并没有被废弃。虽然用于哈希密码非常不安全,但是除了密码之外还有许多其他用途可以进行哈希。例如,为文件创建MD5校验和。 - KyleFarris
2
@balupton 的一行代码虽然简洁,但代价却很高。 - Curcuma_
显示剩余5条评论

267

看一下crypto.createHash(algorithm)

var filename = process.argv[2];
var crypto = require('crypto');
var fs = require('fs');

var md5sum = crypto.createHash('md5');

var s = fs.ReadStream(filename);
s.on('data', function(d) {
  md5sum.update(d);
});

s.on('end', function() {
  var d = md5sum.digest('hex');
  console.log(d + '  ' + filename);
});

s.on() 函数是做什么的?它是否将 md5sum.update(d) 函数注册为每次从 ReadStream 读取数据时执行的函数? - DucRP
@YoniDor 你试过fs.readsync了吗?在经典的while循环中进行摘要,然后确保它完成... ➝ https://dev59.com/zGsz5IYBdhLWcg3w9ssQ#21219407 - Frank N
22
OP希望对一个字符串进行哈希,而不是对文件进行哈希。 - blimpse

88

Node的加密模块API仍然不稳定。

截至4.0.0版本,原生的Crypto模块已经不再不稳定。根据官方文档:

Crypto

稳定性: 2 - 稳定

该API已被证明是满意的。与npm生态系统的兼容性是高优先级的,并且除非绝对必要,否则不会中断。

因此,可以安全地使用本机实现,而无需外部依赖。

供参考,当Crypto模块仍不稳定时,下面提到的模块被建议作为备选解决方案。


您还可以使用sha1md5之一来完成相同的工作。

$ npm install sha1

之后

var sha1 = require('sha1');

var hash = sha1("my message");

console.log(hash); // 104ab42f1193c336aa2cf08a2c946d5c6fd0fcdb
或者
$ npm install md5

然后

var md5 = require('md5');

var hash = md5("my message");

console.log(hash); // 8ba6c19dc1def5702ff5acbf2aeea5aa

(MD5 已不安全,但仍被像 Gravatar 这样的服务使用。)

这些模块的 API 不会改变!


10
我认为利用加密货币比引入一个全新的模块要简单得多且更有效率。 - Valjas
6
根据当前的Node.js文档:"稳定性: 2 - 不稳定;API更改正在讨论中,将尽量减少破坏性更改。" 我的模块的API不会改变。当我最初编写这个模块时,平台上没有内置的crypto模块。另一个优点是,您可以在服务器和客户端两侧使用我的模块。但使用哪个库完全取决于您自己。 - pvorb
7
内置的加密哈希一直提示我“哈希更新失败”。最后我转移到了MD5模块,它完美地工作了。而且调用也更加简单(稍微)。谢谢。 - GJK
2
+1 选择远离加密API(2)不稳定的选项! - Geek Stocks
1
我通过交换标准加密使用的模块,解决了我的Windows机器上Node 0.11.x中一个奇怪的sha1问题。 - Bartvds
显示剩余9条评论

30
sha256("string or binary");

我遇到了另一个答案的问题。建议您设置编码参数为binary,以使用字节字符串并防止Javascript(NodeJS)与Python、PHP、Github等其他语言/服务之间出现不同的哈希结果。

如果您不使用此代码,则可能在NodeJS和Python之间得到不同的哈希结果...

如何获得与Python、PHP、Perl、Github相同的哈希值(并防止问题):

NodeJS正在对字符串的UTF-8表示进行哈希处理。其他语言(如Python、PHP或PERL...)正在对字节字符串进行哈希处理。

我们可以添加binary参数以使用字节字符串。

代码:

const crypto = require("crypto");

function sha256(data) {
    return crypto.createHash("sha256").update(data, "binary").digest("base64");
    //                                               ------  binary: hash the byte string
}

sha256("string or binary");

文档:

  • crypto.createHash(algorithm[, options]): 算法取决于平台上OpenSSL版本支持的可用算法。
  • hash.digest([encoding]): 编码可以是'hex','latin1'或'base64'。(base64较短)。

您可以使用以下内容进行测试:sha256("\xac"), "\xd1", "\xb9", "\xe2", "\xbb", "\x93"等

  • 其他语言(如PHP、Python、Perl...)和我使用的.update(data, "binary")解决方案:

  sha1("\xac") //39527c59247a39d18ad48b9947ea738396a3bc47
  • 默认情况下(不使用二进制文件)的Node.js:

      sha1("\xac") //f50eb35d94f1d75480496e54f4b4a472a9148752
    

  • 30

    简单的一行代码:

    如果您想要UTF8文本哈希:

    const hash = require('crypto').createHash('sha256').update('Hash me', 'utf8').digest('hex');
    

    如果您想使用Python、PHP、Perl或Github获得相同的哈希值:

    const hash = require('crypto').createHash('sha256').update('Hash me', 'binary').digest('hex');
    

    您还可以将'sha256'替换为'sha1''md5''sha256''sha512'


    1
    你好!我该如何做相反的操作?给定一个特定的哈希和一个特定的字符串,检查字符串是否等于哈希。 - Gabriel Augusto
    @GabrielAugusto 对你想要检查的字符串进行哈希处理,并将其与已经哈希处理过的字符串进行比较 :) - CoderMuffin

    26
    crypto 模块可以轻松实现此功能。
    设置:
    // import crypto from 'crypto';
    const crypto = require('crypto');
    
    const sha256 = x => crypto.createHash('sha256').update(x, 'utf8').digest('hex');
    

    使用方法:

    sha256('Hello, world. ');
    

    12

    在这里,您可以对硬件进行所有支持的哈希基准测试,这些哈希由您的node.js版本支持。其中一些是加密哈希,而另一些仅用于校验和。它正在为每个算法计算“Hello World” 100万次。每个算法可能需要大约1-15秒钟的时间(在使用Node.js 4.2.2的标准Google计算引擎上进行了测试)。

    for(var i1=0;i1<crypto.getHashes().length;i1++){
      var Algh=crypto.getHashes()[i1];
      console.time(Algh);
      for(var i2=0;i2<1000000;i2++){
        crypto.createHash(Algh).update("Hello World").digest("hex");
      }
      console.timeEnd(Algh);  
    }
    

    结果:
    DSA:1992毫秒
    DSA-SHA:1960毫秒
    DSA-SHA1:2062毫秒
    DSA-SHA1-old:2124毫秒
    RSA-MD4:1893毫秒
    RSA-MD5:1982毫秒
    RSA-MDC2:2797毫秒
    RSA-RIPEMD160:2101毫秒
    RSA-SHA:1948毫秒
    RSA-SHA1:1908毫秒
    RSA-SHA1-2:2042毫秒
    RSA-SHA224:2176毫秒
    RSA-SHA256:2158毫秒
    RSA-SHA384:2290毫秒
    RSA-SHA512:2357毫秒
    dsaEncryption:1936毫秒
    dsaWithSHA:1910毫秒
    dsaWithSHA1:1926毫秒
    dss1:1928毫秒
    ecdsa-with-SHA1:1880毫秒
    md4:1833毫秒
    md4WithRSAEncryption:1925毫秒
    md5:1863毫秒
    md5WithRSAEncryption:1923毫秒
    mdc2:2729毫秒
    mdc2WithRSA:2890毫秒
    ripemd:2101毫秒
    ripemd160:2153毫秒
    ripemd160WithRSA:2210毫秒
    rmd160:2146毫秒
    sha:1929毫秒
    sha1:1880毫秒
    sha1WithRSAEncryption:1957毫秒
    sha224:2121毫秒
    sha224WithRSAEncryption:2290毫秒
    sha256:2134毫秒
    sha256WithRSAEncryption:2190毫秒
    sha384:2181毫秒
    sha384WithRSAEncryption:2343毫秒
    sha512:2371毫秒
    sha512WithRSAEncryption:2434毫秒
    shaWithRSAEncryption:1966毫秒
    ssl2-md5:1853毫秒
    ssl3-md5:1868毫秒
    ssl3-sha1:1971毫秒
    whirlpool:2578毫秒


    1
    RSA-前缀是什么意思? - balupton

    4

    我想分享我的看法,希望能够帮助到一些人。

    对于那些使用CommonJS的人

    const crypto = require('crypto');
    const secret = 'I love writing code, fixing things and building helpful tools';
    const hash = crypto.createHmac('sha256', secret).digest('hex');
    
    console.log('Hash successfully generated: ', hash);
    

    对于使用ES模块的开发者

    const { createHmac } = await import('crypto');
    const secret = 'I love writing code, fixing things and building helpful tools';
    const hash = createHmac('sha256', secret).digest('hex');
    
    console.log('Hash successfully generated: ', hash);
    

    非常简单! 编程愉快:)


    1
    我使用blueimp-md5,它“与服务器端环境(如Node.js),模块加载器(如RequireJS,Browserify或webpack)和所有Web浏览器兼容。” 像这样使用它:
    var md5 = require("blueimp-md5");
    
    var myHashedString = createHash('GreensterRox');
    
    createHash(myString){
        return md5(myString);
    }
    

    如果需要在公开场合传递哈希值,最好对其进行加盐处理,以增加别人重新生成哈希值的难度。
    createHash(myString){
        var salt = 'HnasBzbxH9';
        return md5(myString+salt);
    }
    

    1
    function md5(a) {
        var r = 0,
            c = "";
        return h(a);
    
        function h(t) {
            return u(l(m(t)))
        }
    
        function l(t) {
            return p(g(f(t), 8 * t.length))
        }
    
        function u(t) {
            for (var e, i = r ? "0123456789ABCDEF" : "0123456789abcdef", n = "", o = 0; o < t.length; o++)
                e = t.charCodeAt(o),
                n += i.charAt(e >>> 4 & 15) + i.charAt(15 & e);
            return n
        }
    
        function m(t) {
            for (var e, i, n = "", o = -1; ++o < t.length;)
                e = t.charCodeAt(o),
                i = o + 1 < t.length ? t.charCodeAt(o + 1) : 0,
                55296 <= e && e <= 56319 && 56320 <= i && i <= 57343 && (e = 65536 + ((1023 & e) << 10) + (1023 & i),
                    o++),
                e <= 127 ? n += String.fromCharCode(e) : e <= 2047 ? n += String.fromCharCode(192 | e >>> 6 & 31, 128 | 63 & e) : e <= 65535 ? n += String.fromCharCode(224 | e >>> 12 & 15, 128 | e >>> 6 & 63, 128 | 63 & e) : e <= 2097151 && (n += String.fromCharCode(240 | e >>> 18 & 7, 128 | e >>> 12 & 63, 128 | e >>> 6 & 63, 128 | 63 & e));
            return n
        }
    
        function f(t) {
            for (var e = Array(t.length >> 2), i = 0; i < e.length; i++)
                e[i] = 0;
            for (i = 0; i < 8 * t.length; i += 8)
                e[i >> 5] |= (255 & t.charCodeAt(i / 8)) << i % 32;
            return e
        }
    
        function p(t) {
            for (var e = "", i = 0; i < 32 * t.length; i += 8)
                e += String.fromCharCode(t[i >> 5] >>> i % 32 & 255);
            return e
        }
    
        function g(t, e) {
            t[e >> 5] |= 128 << e % 32,
                t[14 + (e + 64 >>> 9 << 4)] = e;
            for (var i = 1732584193, n = -271733879, o = -1732584194, s = 271733878, a = 0; a < t.length; a += 16) {
                var r = i,
                    c = n,
                    h = o,
                    l = s;
                n = E(n = E(n = E(n = E(n = N(n = N(n = N(n = N(n = C(n = C(n = C(n = C(n = S(n = S(n = S(n = S(n, o = S(o, s = S(s, i = S(i, n, o, s, t[a + 0], 7, -680876936), n, o, t[a + 1], 12, -389564586), i, n, t[a + 2], 17, 606105819), s, i, t[a + 3], 22, -1044525330), o = S(o, s = S(s, i = S(i, n, o, s, t[a + 4], 7, -176418897), n, o, t[a + 5], 12, 1200080426), i, n, t[a + 6], 17, -1473231341), s, i, t[a + 7], 22, -45705983), o = S(o, s = S(s, i = S(i, n, o, s, t[a + 8], 7, 1770035416), n, o, t[a + 9], 12, -1958414417), i, n, t[a + 10], 17, -42063), s, i, t[a + 11], 22, -1990404162), o = S(o, s = S(s, i = S(i, n, o, s, t[a + 12], 7, 1804603682), n, o, t[a + 13], 12, -40341101), i, n, t[a + 14], 17, -1502002290), s, i, t[a + 15], 22, 1236535329), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 1], 5, -165796510), n, o, t[a + 6], 9, -1069501632), i, n, t[a + 11], 14, 643717713), s, i, t[a + 0], 20, -373897302), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 5], 5, -701558691), n, o, t[a + 10], 9, 38016083), i, n, t[a + 15], 14, -660478335), s, i, t[a + 4], 20, -405537848), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 9], 5, 568446438), n, o, t[a + 14], 9, -1019803690), i, n, t[a + 3], 14, -187363961), s, i, t[a + 8], 20, 1163531501), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 13], 5, -1444681467), n, o, t[a + 2], 9, -51403784), i, n, t[a + 7], 14, 1735328473), s, i, t[a + 12], 20, -1926607734), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 5], 4, -378558), n, o, t[a + 8], 11, -2022574463), i, n, t[a + 11], 16, 1839030562), s, i, t[a + 14], 23, -35309556), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 1], 4, -1530992060), n, o, t[a + 4], 11, 1272893353), i, n, t[a + 7], 16, -155497632), s, i, t[a + 10], 23, -1094730640), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 13], 4, 681279174), n, o, t[a + 0], 11, -358537222), i, n, t[a + 3], 16, -722521979), s, i, t[a + 6], 23, 76029189), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 9], 4, -640364487), n, o, t[a + 12], 11, -421815835), i, n, t[a + 15], 16, 530742520), s, i, t[a + 2], 23, -995338651), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 0], 6, -198630844), n, o, t[a + 7], 10, 1126891415), i, n, t[a + 14], 15, -1416354905), s, i, t[a + 5], 21, -57434055), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 12], 6, 1700485571), n, o, t[a + 3], 10, -1894986606), i, n, t[a + 10], 15, -1051523), s, i, t[a + 1], 21, -2054922799), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 8], 6, 1873313359), n, o, t[a + 15], 10, -30611744), i, n, t[a + 6], 15, -1560198380), s, i, t[a + 13], 21, 1309151649), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 4], 6, -145523070), n, o, t[a + 11], 10, -1120210379), i, n, t[a + 2], 15, 718787259), s, i, t[a + 9], 21, -343485551),
                    i = v(i, r),
                    n = v(n, c),
                    o = v(o, h),
                    s = v(s, l)
            }
            return [i, n, o, s]
        }
    
        function _(t, e, i, n, o, s) {
            return v((a = v(v(e, t), v(n, s))) << (r = o) | a >>> 32 - r, i);
            var a, r
        }
    
        function S(t, e, i, n, o, s, a) {
            return _(e & i | ~e & n, t, e, o, s, a)
        }
    
        function C(t, e, i, n, o, s, a) {
            return _(e & n | i & ~n, t, e, o, s, a)
        }
    
        function N(t, e, i, n, o, s, a) {
            return _(e ^ i ^ n, t, e, o, s, a)
        }
    
        function E(t, e, i, n, o, s, a) {
            return _(i ^ (e | ~n), t, e, o, s, a)
        }
    
        function v(t, e) {
            var i = (65535 & t) + (65535 & e);
            return (t >> 16) + (e >> 16) + (i >> 16) << 16 | 65535 & i
        }
    }
    string = 'hello';
    console.log(md5(string));
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接