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

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


当前回答

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

/**
 * 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”

其他回答

String.prototype.hashCode=函数(){var散列=0,i、 chr;如果(this.length==0)返回哈希;对于(i=0;i<this.length;i++){chr=this.charCodeAt(i);哈希=((哈希<<5)-哈希)+chr;哈希|=0;//转换为32位整数}返回哈希;}const str='收入'console.log(str,str.hashCode())

来源

EDIT

根据我的jsperf测试,公认的答案实际上更快:http://jsperf.com/hashcodelordvlad

原始的,原始的

如果有人感兴趣,这里有一个改进的(更快的)版本,它将在缺少reduce数组功能的旧浏览器上失败。

hashCode=函数{return s.split(“”).reduce(函数(a,b){a=((a<<5)-a)+b.charCodeAt(0);返回a&a;}, 0);}//测试console.log(hashCode(“hello”));console.log(hashCode(“这是一个文本。”));console.log(hashCode(“Luis Fonsi的Despacito”));

单线箭头功能版本:

hashCode=s=>s.split(“”).reduce((a,b)=>{a=((a<<5)-a)+b.charCodeAt(0);返回a&a},0)//测试console.log(hashCode(“hello”));console.log(hashCode(“这是一个文本。”));console.log(hashCode(“Luis Fonsi的Despacito”));

我需要一个类似的函数(但不同)来根据用户名和当前时间生成一个唯一的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/

子级Crypto.digest

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

你确定你不能那样做吗?

你忘了你在使用Javascript吗?

尝试SubleCrypto。它支持SHA-1、SHA-128、SHA-256和SHA-512哈希函数。


异步函数哈希(message/*:string*/){const text_encoder=新的TextEncoder;常量数据=text_encoder.encode(消息);const message_digest=等待window.crypto.intege.digest(“SHA-512”,数据);返回message_digest;}//->阵列缓冲区函数in_hex(data/*:ArrayBuffer*/){const八位字节=新的Uint8Array(数据);const hex=[].map.call(八位字节,八位字节=>八位字节.toString(16).padStart(2,“0”)).join(“”);返回十六进制;}//->字符串(异步函数demo(){console.log(in_hex(等待哈希(“感谢魔法”)));})();

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