我需要将字符串转换为某种形式的哈希。这在JavaScript中是可能的吗?

我没有使用服务器端语言,所以我不能这样做。


当前回答

詹金斯一次一哈希非常好:

//Credits (modified code): Bob Jenkins (http://www.burtleburtle.net/bob/hash/doobs.html)
//See also: https://en.wikipedia.org/wiki/Jenkins_hash_function
//Takes a string of any size and returns an avalanching hash string of 8 hex characters.
function jenkinsOneAtATimeHash(keyString)
{
  let hash = 0;
  for (charIndex = 0; charIndex < keyString.length; ++charIndex)
  {
    hash += keyString.charCodeAt(charIndex);
    hash += hash << 10;
    hash ^= hash >> 6;
  }
  hash += hash << 3;
  hash ^= hash >> 11;
  //4,294,967,295 is FFFFFFFF, the maximum 32 bit unsigned integer value, used here as a mask.
  return (((hash + (hash << 15)) & 4294967295) >>> 0).toString(16)
};

示例:

jenkinsOneAtATimeHash('test')
"31c25ec1"
jenkinsOneAtATimeHash('a')
"ca2e9442"
jenkinsOneAtATimeHash('0')
"6e3c5c6b"

您还可以删除末尾的.toString(16)部分以生成数字:

jenkinsOneAtATimeHash2('test')
834821825
jenkinsOneAtATimeHash2('a')
3392050242
jenkinsOneAtATimeHash2('0')
1849449579

请注意,如果您不需要对字符串或键进行哈希,而只需要凭空生成哈希,则可以使用:

window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16)

示例:

window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16)
"6ba9ea7"
window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16)
"13fe7edf"
window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16)
"971ffed4"

与上面相同,您可以删除末尾的`.toString(16)部分以生成数字:

window.crypto.getRandomValues(new Uint32Array(1))[0]
1154752776
window.crypto.getRandomValues(new Uint32Array(1))[0]
3420298692
window.crypto.getRandomValues(new Uint32Array(1))[0]
1781389127

注意:您也可以使用此方法一次生成多个值,例如:

window.crypto.getRandomValues(new Uint32Array(3))
Uint32Array(3) [ 2050530949, 3280127172, 3001752815 ]

其他回答

我基于FNV的乘法+Xor方法的快速(非常长)一行:

my_string.split('').map(v=>v.charCodeAt(0)).reduce((a,v)=>a+((a<<7)+(a<<3))^v).toString(16);

添加这一点是因为还没有人这样做,而这似乎是用哈希来要求和实现的,但它总是做得很糟糕。。。

这需要一个字符串输入和您希望哈希值相等的最大值,并根据字符串输入生成一个唯一的数字。

您可以使用它来生成图像数组中的唯一索引(如果您希望为用户返回一个特定的化身,该化身是随机选择的,但也是基于其名称选择的,因此它将始终分配给具有该名称的人)。

当然,您也可以使用它将索引返回到颜色数组中,例如根据某人的姓名生成独特的化身背景颜色。

function hashInt (str, max = 1000) {
    var hash = 0;
    for (var i = 0; i < str.length; i++) {
      hash = ((hash << 5) - hash) + str.charCodeAt(i);
      hash = hash & hash;
    }
    return Math.round(max * Math.abs(hash) / 2147483648);
}

函数hashCode(str){return str.split(“”).reduce((prevHash,currVal)=>(((prevHash<<5)-previvHash)+currVal.charCodeAt(0))|0,0);}//测试console.log(“hashCode(\“Hello!\”):“,hashCode('Hello!'));

这将基于传入的任意数量的参数生成一致的哈希:

/**
 * Generates a hash from params passed in
 * @returns {string} hash based on params
 */
function fastHashParams() {
    var args = Array.prototype.slice.call(arguments).join('|');
    var hash = 0;
    if (args.length == 0) {
        return hash;
    }
    for (var i = 0; i < args.length; i++) {
        var char = args.charCodeAt(i);
        hash = ((hash << 5) - hash) + char;
        hash = hash & hash; // Convert to 32bit integer
    }
    return String(hash);
}

fastHashParams('hello world')输出“990433808”

fastHashParams('this',1,'has','lots','of','params',true)输出“1465480334”

我有点惊讶,还没有人谈论新的SubtleCryptoAPI。

要从字符串中获取哈希,可以使用suble.desumest方法:

函数getHash(str,algo=“SHA-256”){let strBuf=newTextEncoder().encode(str);return crypto.define.digest(算法,strBuf).then(哈希=>{window.hash=哈希;//这里hash是arrayBuffer,//所以我们将其转换为十六进制版本let result=“”;const view=新数据视图(哈希);for(设i=0;i<hash.byteLength;i+=4){result+=('000000000'+view.getUint32(i).toString(16)).sslice(-8);}返回结果;});}getHash('hello world').then(哈希=>{console.log(哈希);});