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

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


当前回答

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

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

其他回答

我需要一个类似的函数(但不同)来根据用户名和当前时间生成一个唯一的ish ID。因此:

window.newId = ->
  # create a number based on the username
  unless window.userNumber?
    window.userNumber = 0
  for c,i in window.MyNamespace.userName
    char = window.MyNamespace.userName.charCodeAt(i)
    window.MyNamespace.userNumber+=char
  ((window.MyNamespace.userNumber + Math.floor(Math.random() * 1e15) + new Date().getMilliseconds()).toString(36)).toUpperCase()

生产:

2DVFXJGEKL
6IZPAKFQFL
ORGOENVMG
... etc 

编辑2022年7月:正如@canRau指出的那样,shortid的作者现在更喜欢nanoidhttps://github.com/ai/nanoid/

这是一个改进的、性能更好的变体,与Java对CharSequence的标准object.hashCode()的实现相匹配。

String.prototype.hashCode = function() {
    var hash = 0, i = 0, len = this.length;
    while ( i < len ) {
        hash  = ((hash << 5) - hash + this.charCodeAt(i++)) << 0;
    }
    return hash;
};

这里还有一个只返回正散列码的函数:

String.prototype.hashcode = function() {
    return this.hashCode()+ 2147483647 + 1;
};

这里有一个匹配的Java,它只返回正散列码:

public static long hashcode(Object obj) {
    return ((long) obj.hashCode()) + Integer.MAX_VALUE + 1l;
}

对于那些不想将其附加到字符串的人,没有原型:

function hashCode(str) {
    var hash = 0, i = 0, len = str.length;
    while ( i < len ) {
        hash  = ((hash << 5) - hash + str.charCodeAt(i++)) << 0;
    }
    return hash;
}

function hashcode(str) {
    hashCode(str) + 2147483647 + 1;
}

享受

我有点惊讶,还没有人谈论新的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(哈希);});

@esmiralha答案的略微简化版本。

我不会在这个版本中重写String,因为这可能会导致一些不希望的行为。

function hashCode(str) {
    var hash = 0;
    for (var i = 0; i < str.length; i++) {
        hash = ~~(((hash << 5) - hash) + str.charCodeAt(i));
    }
    return hash;
}

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

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

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

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

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);
}