我需要将字符串转换为某种形式的哈希。这在JavaScript中是可能的吗?
我没有使用服务器端语言,所以我不能这样做。
我需要将字符串转换为某种形式的哈希。这在JavaScript中是可能的吗?
我没有使用服务器端语言,所以我不能这样做。
当前回答
我有点惊讶,还没有人谈论新的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(哈希);});
其他回答
得益于mar10的示例,我找到了一种在C#和Javascript中为FNV-1a获得相同结果的方法。如果存在unicode字符,为了提高性能,将放弃上面的部分。不知道为什么在哈希时维护这些路径会很有用,因为我现在只哈希url路径。
C#版本
private static readonly UInt32 FNV_OFFSET_32 = 0x811c9dc5; // 2166136261
private static readonly UInt32 FNV_PRIME_32 = 0x1000193; // 16777619
// Unsigned 32bit integer FNV-1a
public static UInt32 HashFnv32u(this string s)
{
// byte[] arr = Encoding.UTF8.GetBytes(s); // 8 bit expanded unicode array
char[] arr = s.ToCharArray(); // 16 bit unicode is native .net
UInt32 hash = FNV_OFFSET_32;
for (var i = 0; i < s.Length; i++)
{
// Strips unicode bits, only the lower 8 bits of the values are used
hash = hash ^ unchecked((byte)(arr[i] & 0xFF));
hash = hash * FNV_PRIME_32;
}
return hash;
}
// Signed hash for storing in SQL Server
public static Int32 HashFnv32s(this string s)
{
return unchecked((int)s.HashFnv32u());
}
JavaScript版本
var utils = utils || {};
utils.FNV_OFFSET_32 = 0x811c9dc5;
utils.hashFnv32a = function (input) {
var hval = utils.FNV_OFFSET_32;
// Strips unicode bits, only the lower 8 bits of the values are used
for (var i = 0; i < input.length; i++) {
hval = hval ^ (input.charCodeAt(i) & 0xFF);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
return hval >>> 0;
}
utils.toHex = function (val) {
return ("0000000" + (val >>> 0).toString(16)).substr(-8);
}
子级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(等待哈希(“感谢魔法”)));})();
我需要一个类似的函数(但不同)来根据用户名和当前时间生成一个唯一的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/
这里是一个紧凑的ES6友好可读片段
const stringHashCode = str => {
let hash = 0
for (let i = 0; i < str.length; ++i)
hash = Math.imul(31, hash) + str.charCodeAt(i)
return hash | 0
}
这是一个快速而简洁的版本,改编自这里:
String.prototype.hashCode = function() {
var hash = 5381, i = this.length
while(i)
hash = (hash * 33) ^ this.charCodeAt(--i)
return hash >>> 0;
}