我需要将字符串转换为某种形式的哈希。这在JavaScript中是可能的吗?
我没有使用服务器端语言,所以我不能这样做。
我需要将字符串转换为某种形式的哈希。这在JavaScript中是可能的吗?
我没有使用服务器端语言,所以我不能这样做。
当前回答
子级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(等待哈希(“感谢魔法”)));})();
其他回答
得益于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);
}
这将基于传入的任意数量的参数生成一致的哈希:
/**
* 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 = function() {
var hash = 5381, i = this.length
while(i)
hash = (hash * 33) ^ this.charCodeAt(--i)
return hash >>> 0;
}
我尝试了将字符代码转换为十六进制字符串的简单串联。这有一个相对狭窄的目的,即只需要与服务器端交换SHORT字符串(例如标题、标签)的哈希表示,因为不相关的原因,服务器端无法轻松实现接受的hashCode Java端口。显然,这里没有安全应用程序。
String.prototype.hash = function() {
var self = this, range = Array(this.length);
for(var i = 0; i < this.length; i++) {
range[i] = i;
}
return Array.prototype.map.call(range, function(i) {
return self.charCodeAt(i).toString(16);
}).join('');
}
这可以通过Undercore变得更加简洁和浏览器宽容。例子:
"Lorem Ipsum".hash()
"4c6f72656d20497073756d"
我想,如果你想以类似的方式对更大的字符串进行散列,你可以减少字符代码并对结果进行十六进制,而不是将单个字符连接在一起:
String.prototype.hashLarge = function() {
var self = this, range = Array(this.length);
for(var i = 0; i < this.length; i++) {
range[i] = i;
}
return Array.prototype.reduce.call(range, function(sum, i) {
return sum + self.charCodeAt(i);
}, 0).toString(16);
}
'One time, I hired a monkey to take notes for me in class. I would just sit back with my mind completely blank while the monkey scribbled on little pieces of paper. At the end of the week, the teacher said, "Class, I want you to write a paper using your notes." So I wrote a paper that said, "Hello! My name is Bingo! I like to climb on things! Can I have a banana? Eek, eek!" I got an F. When I told my mom about it, she said, "I told you, never trust a monkey!"'.hashLarge()
"9ce7"
当然,与此方法冲突的风险更大,尽管您可以在reduce中摆弄算法,但您希望多样化并延长哈希。
函数hashCode(str){return str.split(“”).reduce((prevHash,currVal)=>(((prevHash<<5)-previvHash)+currVal.charCodeAt(0))|0,0);}//测试console.log(“hashCode(\“Hello!\”):“,hashCode('Hello!'));