我正在通过javascript进行一些缓存。我有一个方法,它接受一个字符串数组并返回一个处理结果。我想从这些字符串创建一个唯一的ID,然后将其用作对象中的键来存储结果。这样,缓存中的密钥占用的内存尽可能少。
本质上我想要像SHA1这样的东西,但是对于javascript。
知道我怎么能做到这一点吗?
感谢。
答案 0 :(得分:3)
不幸的是,如果不使用数组的全部内容作为密钥,就无法获得100%保证唯一性。大多数优秀的非加密哈希只会将冲突减少到哈希表中可接受的良好性能,但您仍需要验证整个内容是否匹配。
即使像SHA-1或MD5这样的加密哈希仍然会发生冲突,但在大多数情况下这种情况极不可能。如果那还不错,我可能会选择SHA-1。否则,我会将数组转换为字符串以用作密钥,让JavaScript担心散列和冲突。
在任何情况下,你可能都在交易性能(JavaScript所做的原生哈希可能比你在JavaScript中编写的任何东西 更快并且可能是空间的绝对正确性。
此外,无论您是自己进行散列,还是让JavaScript进行散列,请注意如何将数组转换为字符串,因为简单的连接可能不是唯一的(即使使用分隔符)。
答案 1 :(得分:1)
不使用哈希,你就不会得到一些独特的东西。
执行myArray.join()
可能保证唯一,但可能会消耗大量内存并遇到不具备唯一性的边缘情况。
最好的方法是在JavaScript中使用哈希算法的实现。
答案 2 :(得分:1)
根据数组中值的性质,您可能能够快速烹饪并适合您的情况。考虑碰撞的可能性及其后果是很重要的。由于我们目前没有所有这些信息,因此我只能提供一些工作起点:
(length of string concat as int) + '/' + (number of strings as int) + '/' + (first char of each string)
也可能没问题,具体取决于您的期望值最后,这是从C#移植的string.GetHashCode()
的实现。如果它对.NET来说足够好,那对你来说可能已经足够了。
var str = "concatenation of all array values";
var hash1 = (5381<<16) + 5381;
var hash2 = hash1;
var hashPos = 0;
while(hashPos < str.length) {
hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ str.charCodeAt(hashPos);
if( hashPos == str.length - 1) {
break;
}
hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ str.charCodeAt(hashPos + 1);
hashPos += 2;
}
return hash1 + (hash2 * 1566083941);
答案 3 :(得分:0)
你想在JavaScript中使用sha1吗?这里 - &gt; http://pajhome.org.uk/crypt/md5/sha1.html
答案 4 :(得分:-1)
也许这个:
var newDate = new Date;
var uid = newDate.getTime();
或者这个:
var uid = Math.random() * Math.pow(10, 17) + Math.random() * Math.pow(10, 17) + Math.random() * Math.pow(10, 17) + Math.random() * Math.pow(10, 17));
有许多方法可以获得与唯一ID一样接近的内容,并且由于您正在使用javascript进行缓存,因此它变得更容易。这是一个选择最适合你的问题。