JavaScript的简单(非安全)哈希函数?

mjs*_*mjs 116 javascript hash md5 sha1

可能重复:
在Javascript/jQuery中从字符串生成哈希

任何人都可以建议一个简单的(即数十行代码,而不是数百行)散列函数(与浏览器兼容)JavaScript?理想情况下,我想要一些东西,当传递一个字符串作为输入时,产生类似于32字符十六进制字符串的东西,它是MD5,SHA1等的典型输出.它不一定是加密安全的,只是合理地抵抗冲突.(我的初始用例是URL,但我可能希望将来在其他字符串上使用它.)

小智 118

我自己没有验证这一点,但你可以看看Java的String.hashCode()方法的JavaScript实现.似乎相当短.

使用此原型,您可以简单地调用.hashCode()任何字符串,例如"some string".hashCode(),并接收数字哈希码(更具体地说,Java等价物),例如1395333309.

String.prototype.hashCode = function() {
    var hash = 0;
    if (this.length == 0) {
        return hash;
    }
    for (var i = 0; i < this.length; i++) {
        var char = this.charCodeAt(i);
        hash = ((hash<<5)-hash)+char;
        hash = hash & hash; // Convert to 32bit integer
    }
    return hash;
}
Run Code Online (Sandbox Code Playgroud)

  • 真的很酷!唯一的问题就是使用非Ecmascript方法污染`String`的`prototype`.我会把它重写为一个独立的函数,也许把它放在你的util库中. (21认同)
  • SHA1和MD5非常慢.我做了一堆比较测试,这个Java哈希的实现证明是最快的,并且与我试过的其他任何冲突相比,几乎没有碰撞(在相对统一的数据上).很短很甜. (6认同)
  • 一行: `Array.from(str).reduce((hash, char) =&gt; 0 | (31 * hash + char.charCodeAt(0)), 0)` (其中 `str` 是字符串) (5认同)
  • 另一件事是它创建了一个全局变量`i`,因为他忘记了循环中的`var`关键字.但这些问题很容易解决. (3认同)
  • Java的String.hashCode()文档,因为本文中的链接具有404:http://devdocs.io/openjdk~8/java/lang/string#hashCode-- (2认同)
  • 微观优化:删除`if(this.length == 0){return hash}`块,因为它仍然是多余的(在length为正数时执行`for`,否则默认返回0)。我想念什么吗? (2认同)
  • 由于我们在 2019 年编写 javascript 的方式不同,因此这里是相同的东西,但没有将其绑定到 String 原型...... ``` function hashCode(source) { let hash = 0; if (source.length == 0) { 返回哈希值;} for (var i = 0; i &lt; source.length; i++) { var char = source.charCodeAt(i); hash = ((hash&lt;&lt;5)-hash)+char; 散列 = 散列 &amp; 散列;// 转换为 32 位整数 } return hash; }``` (2认同)
  • @Cyber​​netic,散列是一种单向技术,不可逆且无法撤消 (2认同)
  • 该算法的一次碰撞:*FB* 和 *Ea* (2认同)

sil*_*lex 9

用JS编写的哈希函数有很多实现.例如:

如果你不需要安全性,你也可以使用不是哈希函数的base64,没有固定的输出,可以简单地由用户解码,但看起来更轻,可以用于隐藏值:http:// www. webtoolkit.info/javascript-base64.html

  • base64 甚至比输入还要长,顺便澄清一下。 (6认同)
  • 字符串的base64编码与原始字符串的长度大致相同; 我想要一些更短的东西,比如哈希. (4认同)

Ste*_*lip 6

查看这些实现

  • OP 询问的是非安全、非加密哈希值,MD5 和 SHA-1 是旨在保证安全的加密哈希值。 (2认同)

For*_*rdi 6

简单的对象哈希器:

(function () {
    Number.prototype.toHex = function () {
        var ret = ((this<0?0x8:0)+((this >> 28) & 0x7)).toString(16) + (this & 0xfffffff).toString(16);
        while (ret.length < 8) ret = '0'+ret;
        return ret;
    };
    Object.hashCode = function hashCode(o, l) {
        l = l || 2;
        var i, c, r = [];
        for (i=0; i<l; i++)
            r.push(i*268803292);
        function stringify(o) {
            var i,r;
            if (o === null) return 'n';
            if (o === true) return 't';
            if (o === false) return 'f';
            if (o instanceof Date) return 'd:'+(0+o);
            i=typeof o;
            if (i === 'string') return 's:'+o.replace(/([\\\\;])/g,'\\$1');
            if (i === 'number') return 'n:'+o;
            if (o instanceof Function) return 'm:'+o.toString().replace(/([\\\\;])/g,'\\$1');
            if (o instanceof Array) {
                r=[];
                for (i=0; i<o.length; i++) 
                    r.push(stringify(o[i]));
                return 'a:'+r.join(';');
            }
            r=[];
            for (i in o) {
                r.push(i+':'+stringify(o[i]))
            }
            return 'o:'+r.join(';');
        }
        o = stringify(o);
        for (i=0; i<o.length; i++) {
            for (c=0; c<r.length; c++) {
                r[c] = (r[c] << 13)-(r[c] >> 19);
                r[c] += o.charCodeAt(i) << (r[c] % 24);
                r[c] = r[c] & r[c];
            }
        }
        for (i=0; i<r.length; i++) {
            r[i] = r[i].toHex();
        }
        return r.join('');
    }
}());
Run Code Online (Sandbox Code Playgroud)

这里的核心是字符串生成器,它只是将任何对象转换为唯一的字符串。然后 hashCode 对该对象运行,将字符串化对象的字符散列在一起。

为了获得额外的好处,请导出字符串生成器并创建一个解析器。

  • 2012 年 3 月。当时我无法假设 JSON 在某个浏览器中可以正常工作。此外,JSON 删除了函数,因此使用 JSON 作为字符串生成器时它们无法进行哈希处理。 (2认同)