मुझे स्ट्रिंग्स को हैश के किसी रूप में बदलने की आवश्यकता है। क्या यह जावास्क्रिप्ट में संभव है?
मैं सर्वर-साइड भाषा का उपयोग नहीं कर रहा हूं, इसलिए मैं इसे इस तरह से नहीं कर सकता।
मुझे स्ट्रिंग्स को हैश के किसी रूप में बदलने की आवश्यकता है। क्या यह जावास्क्रिप्ट में संभव है?
मैं सर्वर-साइड भाषा का उपयोग नहीं कर रहा हूं, इसलिए मैं इसे इस तरह से नहीं कर सकता।
जवाबों:
Object.defineProperty(String.prototype, 'hashCode', {
value: function() {
var hash = 0, i, chr;
for (i = 0; i < this.length; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
});
स्रोत: http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
hash << 5 - hash
रूप में ही है, hash * 31 + char
लेकिन बहुत तेजी से है। यह अच्छा है क्योंकि यह बहुत तेज़ है, और 31 एक छोटा प्राइम है। वहां जीत मिली।
(hash * 31) + char
द्वारा उत्पादित आउटपुट शिफ्ट-आधारित कोड द्वारा उत्पादित आउटपुट के समान है ((hash<<5)-hash)+char
, यहां तक कि बहुत लंबे तार के लिए भी (मैंने इसे एक लाख से अधिक वर्णों के साथ परीक्षण किया है), इसलिए यह "अनुपयोगी" शब्दों में नहीं है सटीकता की। संख्या-आधारित और पारी-आधारित दोनों संस्करणों के लिए जटिलता O (n) है, इसलिए यह जटिलता के संदर्भ में "अनुपयोगी" नहीं है।
n
सबसे बड़ा क्या है n
जिसके लिए मैं संभवतः टकराव नहीं कर सकता हूं?
var hashCode = function hashCode (str) {etc...}
? और फिर उपयोग के रूप में hashCode("mystring")
?
संपादित करें
मेरे jsperf परीक्षणों के आधार पर, स्वीकृत उत्तर वास्तव में तेज़ है: http://jsperf.com/hashcodelordvlad
मूल
अगर किसी को दिलचस्पी है, तो यहां एक बेहतर (तेज़) संस्करण है, जो पुराने ब्राउज़र पर विफल हो जाएगा जिनके पास reduce
सरणी फ़ंक्शन की कमी है ।
hashCode = function(s){
return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
एक-लाइनर तीर फ़ंक्शन संस्करण:
hashCode = s => s.split('').reduce((a,b)=>{a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)
नोट: सबसे अच्छा 32-बिट हैश के साथ भी टकराव होगा अभी या बाद में पाए जाते हैं।
हैश टकराव की संभावना की गणना इस प्रकार की जा सकती है , जैसा कि ( यहाँ देखें )। यह अंतर्ज्ञान से अधिक हो सकता है पता चलता है:
एक 32-बिट हैश और k = 10,000 वस्तुओं को मानते हुए, एक टकराव 1.2% की संभावना के साथ होगा। 77,163 नमूनों के लिए संभावना 50% हो जाती है! ( कैलकुलेटर )।
मैं नीचे एक समाधान सुझाता हूं।
इस प्रश्न के उत्तर में कि
अद्वितीयता और गति के लिए कौन सा हैशिंग एल्गोरिथ्म सबसे अच्छा है? , इयान बॉयड ने गहराई से विश्लेषण में एक अच्छा पोस्ट किया । संक्षेप में (जैसा कि मैं इसकी व्याख्या करता हूं), वह इस निष्कर्ष पर पहुंचता है कि मुरम सबसे अच्छा है, उसके बाद एफएनवी -1 ए।
जावा के String.hashCode () एल्गोरिथ्म जो एस्मीराल्हा ने प्रस्तावित किया था, वह डीजेबी 2 का एक संस्करण प्रतीत होता है।
बड़े इनपुट स्ट्रिंग्स के साथ कुछ बेंचमार्क: http://jsperf.com/32-bit-hash
जब शॉर्ट इनपुट स्ट्रिंग्स हैशेड होते हैं, तो डीजे 2 बी और एफएनवी -1 ए के सापेक्ष मुरम का प्रदर्शन गिर जाता है: http ://jsperf-32- बिट-हैश / 3
तो सामान्य तौर पर मैं murmur3 की सिफारिश करूंगा।
जावास्क्रिप्ट कार्यान्वयन के लिए यहां देखें:
https://github.com/garycourt/murmurhash-js
यदि इनपुट स्ट्रिंग कम हैं और वितरण गुणवत्ता की तुलना में प्रदर्शन अधिक महत्वपूर्ण है, तो डीजेबी 2 का उपयोग करें (जैसा कि एस्मीराल्हा द्वारा स्वीकृत उत्तर द्वारा प्रस्तावित किया गया है)।
यदि गुणवत्ता और छोटे कोड का आकार गति से अधिक महत्वपूर्ण है, तो मैं FNV-1a के कार्यान्वयन ( इस कोड के आधार पर ) का उपयोग करता हूं ।
/**
* Calculate a 32 bit FNV-1a hash
* Found here: https://gist.github.com/vaiorabbit/5657561
* Ref.: http://isthe.com/chongo/tech/comp/fnv/
*
* @param {string} str the input value
* @param {boolean} [asString=false] set to true to return the hash value as
* 8-digit hex string instead of an integer
* @param {integer} [seed] optionally pass the hash of the previous chunk
* @returns {integer | string}
*/
function hashFnv32a(str, asString, seed) {
/*jshint bitwise:false */
var i, l,
hval = (seed === undefined) ? 0x811c9dc5 : seed;
for (i = 0, l = str.length; i < l; i++) {
hval ^= str.charCodeAt(i);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
if( asString ){
// Convert to 8 digit hex string
return ("0000000" + (hval >>> 0).toString(16)).substr(-8);
}
return hval >>> 0;
}
टकराव की संभावना में सुधार
जैसा कि यहाँ बताया गया है , हम इस ट्रिक का उपयोग करके हैश बिट साइज़ को बढ़ा सकते हैं:
function hash64(str) {
var h1 = hash32(str); // returns 32 bit (as 8 byte hex string)
return h1 + hash32(h1 + str); // 64 bit (as 16 byte hex string)
}
देखभाल के साथ इसका उपयोग करें और हालांकि बहुत ज्यादा उम्मीद न करें।
("0000000" + (hval >>> 0).toString(16)).substr(-8);
? क्या ऐसा नहीं है (hval >>> 0).toString(16)
?
hval
, (hval >>> 0).toString(16)
8 अक्षर से कम हो सकता है, इसलिए आप इसे शून्य के साथ पैड करते हैं। मैं सिर्फ भ्रमित था क्योंकि (hval >>> 0).toString(16)
हमेशा मेरे लिए एक बिल्कुल 8 वर्ण स्ट्रिंग का परिणाम था।
Math.imul
फ़ंक्शन का उपयोग करते हुए एफएनवी 1 ए बेहद तेज हो सकता है। यह अकेले इसे शीर्ष बेंचमार्क बनाता है, और अंततः लंबे समय में डीजेबी 2 से बेहतर विकल्प है।
ES6 में स्वीकृत उत्तर के आधार पर । छोटे, रखरखाव योग्य और आधुनिक ब्राउज़रों में काम करता है।
function hashCode(str) {
return str.split('').reduce((prevHash, currVal) =>
(((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);
}
// Test
console.log("hashCode(\"Hello!\"): ", hashCode('Hello!'));
EDIT (2019-11-04) :
एक-लाइनर तीर फ़ंक्शन संस्करण:
const hashCode = s => s.split('').reduce((a,b) => (((a << 5) - a) + b.charCodeAt(0))|0, 0)
// test
console.log(hashCode('Hello!'))
str += ""
हैशिंग से पहले जोड़ा गया था कि str.split is not a function
जब गैर-तार को मापदंडों के रूप में पारित किया गया था, तब से बचने के लिए हैशिंग
hash |= 0
को 32 बिट इंट में बदलने के लिए उपयोग करता है। यह कार्यान्वयन नहीं करता है। क्या यह एक बग है?
लगभग आधे उत्तर जावा के कार्यान्वयन हैं
String.hashCode
, जो न तो उच्च गुणवत्ता वाले हैं और न ही सुपर फास्ट हैं। यह बहुत खास नहीं है, यह सिर्फ प्रत्येक चरित्र के लिए 31 से गुणा करता है। इसे केवल एक लाइन में और कुशलता से लागू किया जा सकता है, और इसके साथ बहुत तेज़ हैMath.imul
:
hashCode=s=>{for(var i=0,h;i<s.length;i++)h=Math.imul(31,h)+s.charCodeAt(i)|0;return h}
उस रास्ते से बाहर, यहाँ कुछ बेहतर है - cyrb53 , एक सरल लेकिन उच्च गुणवत्ता वाला 53-बिट हैश। यह काफी तेज़ है, बहुत अच्छा हैश वितरण प्रदान करता है, और किसी भी 32-बिट हैश की तुलना में टकराव की दर काफी कम है ।
const cyrb53 = function(str, seed = 0) {
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ h1>>>16, 2246822507) ^ Math.imul(h2 ^ h2>>>13, 3266489909);
h2 = Math.imul(h2 ^ h2>>>16, 2246822507) ^ Math.imul(h1 ^ h1>>>13, 3266489909);
return 4294967296 * (2097151 & h2) + (h1>>>0);
};
प्रसिद्ध मुरमुरश / xxHash एल्गोरिदम के समान, यह गुणा और Xorshift के संयोजन का उपयोग करता है हैश उत्पन्न करने के लिए , लेकिन पूरी तरह से नहीं। परिणामस्वरूप यह जावास्क्रिप्ट में या तो तेजी से लागू होता है और इसे लागू करने के लिए काफी सरल है।
यह हिमस्खलन (गैर-सख्त) को प्राप्त करता है, जिसका अर्थ है कि इनपुट में छोटे परिवर्तन से आउटपुट में बड़े परिवर्तन होते हैं, जिसके परिणामस्वरूप हैश यादृच्छिक दिखाई देता है:
0xc2ba782c97901 = cyrb53("a")
0xeda5bc254d2bf = cyrb53("b")
0xe64cc3b748385 = cyrb53("revenge")
0xd85148d13f93a = cyrb53("revenue")
आप एक ही इनपुट के वैकल्पिक धाराओं के लिए एक बीज भी दे सकते हैं:
0xee5e6598ccd5c = cyrb53("revenue", 1)
0x72e2831253862 = cyrb53("revenue", 2)
0x0de31708e6ab7 = cyrb53("revenue", 3)
तकनीकी रूप से यह 64-बिट हैश (समानांतर में दो असंबंधित 32-बिट हैश) है, लेकिन जावास्क्रिप्ट 53-बिट पूर्णांक तक सीमित है। यदि आवश्यक हो, पूर्ण 64-बिट आउटपुट अभी भी उपयोग किया जा सकता है हेक्स स्ट्रिंग या सरणी के लिए रिटर्न लाइन को बदलकर किया ।
ध्यान रखें कि हेक्स स्ट्रिंग्स का निर्माण प्रदर्शन-महत्वपूर्ण परिस्थितियों में बैच प्रसंस्करण को काफी धीमा कर सकता है।
return (h2>>>0).toString(16).padStart(8,0)+(h1>>>0).toString(16).padStart(8,0);
// or
return [h2>>>0, h1>>>0];
और सिर्फ मज़े के लिए, यहाँ पर FNV या DJB2 की तुलना में उच्च गुणवत्ता के साथ 89 वर्णों में न्यूनतम 32-बिट हैश है :
TSH=s=>{for(var i=0,h=9;i<s.length;)h=Math.imul(h^s.charCodeAt(i++),9**9);return h^h>>>9}
ch
आरंभ किया गया है?
'imul'
।
यदि यह किसी की मदद करता है, तो मैंने शीर्ष दो उत्तरों को पुराने-ब्राउज़र-सहिष्णु संस्करण में संयोजित किया, जो reduce
कि उपलब्ध होने पर तेज़ संस्करण का उपयोग करता है और यदि यह नहीं है तो एस्मीराल्हा के समाधान पर वापस आ जाता है।
/**
* @see http://stackoverflow.com/q/7616461/940217
* @return {number}
*/
String.prototype.hashCode = function(){
if (Array.prototype.reduce){
return this.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
var hash = 0;
if (this.length === 0) return hash;
for (var i = 0; i < this.length; i++) {
var character = this.charCodeAt(i);
hash = ((hash<<5)-hash)+character;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
उपयोग की तरह है:
var hash = "some string to be hashed".hashCode();
String.prototype.hashCode = function(){ var hash = 5381; if (this.length === 0) return hash; for (var i = 0; i < this.length; i++) { var character = this.charCodeAt(i); hash = ((hash<<5)+hash)^character; // Convert to 32bit integer } return hash; }
यह एक परिष्कृत और बेहतर प्रदर्शन वाला संस्करण है:
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;
};
यह जावा के मानक के कार्यान्वयन से मेल खाता है object.hashCode()
यहाँ भी एक है जो केवल सकारात्मक हैशकोड लौटाता है:
String.prototype.hashcode = function() {
return (this.hashCode() + 2147483647) + 1;
};
और यहाँ जावा के लिए एक मेल है जो केवल सकारात्मक हैशकोड लौटाता है:
public static long hashcode(Object obj) {
return ((long) obj.hashCode()) + Integer.MAX_VALUE + 1l;
}
का आनंद लें!
मुझे थोड़ी हैरानी हुई कि किसी ने भी अभी तक SubtleCrypto API के बारे में बात नहीं की है।
एक स्ट्रिंग से हैश प्राप्त करने के लिए, आप subtle.digest
विधि का उपयोग कर सकते हैं :
function getHash(str, algo = "SHA-256") {
let strBuf = new TextEncoder('utf-8').encode(str);
return crypto.subtle.digest(algo, strBuf)
.then(hash => {
window.hash = hash;
// here hash is an arrayBuffer,
// so we'll connvert it to its hex version
let result = '';
const view = new DataView(hash);
for (let i = 0; i < hash.byteLength; i += 4) {
result += ('00000000' + view.getUint32(i).toString(16)).slice(-8);
}
return result;
});
}
getHash('hello world')
.then(hash => {
console.log(hash);
});
var promise = crypto.subtle.digest({name: "SHA-256"}, Uint8Array.from(data)); promise.then(function(result){ console.log(Array.prototype.map.call(new Uint8Array(result), x => x.toString(16).padStart(2, '0')).join('')); });
crypto
बिल्कुल प्रदर्शन नहीं है।
उदाहरण के लिए mar10 द्वारा धन्यवाद, मुझे FNV-1a के लिए 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());
}
जावास्क्रिप्ट संस्करण
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);
}
Math.imul
का उपयोग गुणन चरण के लिए किया जा सकता है, जो प्रदर्शन में सुधार करता है । केवल मुद्दा यह है कि यह IE11 में बिना शिम के काम नहीं करेगा ।
एक तेज़ और संक्षिप्त जिसे यहाँ से अनुकूलित किया गया था :
String.prototype.hashCode = function() {
var hash = 5381, i = this.length
while(i)
hash = (hash * 33) ^ this.charCodeAt(--i)
return hash >>> 0;
}
मुझे उपयोगकर्ता नाम और वर्तमान समय के आधार पर एक विशिष्ट-ईश आईडी बनाने के लिए एक समान फ़ंक्शन (लेकिन अलग) की आवश्यकता थी। इसलिए:
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
संपादित करें जून 2015: नए कोड के लिए मैं संक्षिप्त का उपयोग करता हूं: https://www.npmjs.com/package/shortid
मैं सर्वर-साइड भाषा का उपयोग नहीं कर रहा हूं, इसलिए मैं इसे इस तरह से नहीं कर सकता।
क्या आप वाकई इस तरह से नहीं कर सकते हैं? ?
क्या आप भूल गए कि आप जावास्क्रिप्ट का उपयोग कर रहे हैं, कभी विकसित होने वाली भाषा?
कोशिश करो SubtleCrypto
। यह SHA-1, SHA-128, SHA-256 और SHA-512 हैश फ़ंक्शन का समर्थन करता है।
async function hash(message/*: string */) {
const text_encoder = new TextEncoder;
const data = text_encoder.encode(message);
const message_digest = await window.crypto.subtle.digest("SHA-512", data);
return message_digest;
} // -> ArrayBuffer
function in_hex(data/*: ArrayBuffer */) {
const octets = new Uint8Array(data);
const hex = [].map.call(octets, octet => octet.toString(16).padStart(2, "0")).join("");
return hex;
} // -> string
(async function demo() {
console.log(in_hex(await hash("Thanks for the magic.")));
})();
मैं पार्टी में देर से आता हूं, लेकिन आप इस मॉड्यूल का उपयोग कर सकते हैं: क्रिप्टो :
const crypto = require('crypto');
const SALT = '$ome$alt';
function generateHash(pass) {
return crypto.createHmac('sha256', SALT)
.update(pass)
.digest('hex');
}
इस फ़ंक्शन का परिणाम हमेशा 64
वर्ण स्ट्रिंग होता है; कुछ इस तरह:"aa54e7563b1964037849528e7ba068eb7767b1fab74a8d80fe300828b996714a"
मैंने दो सॉल्यूशंस (यूजर्स एस्मीराल्हा और लॉर्डव्लाड) को एक फंक्शन में मिला दिया है, जो उन ब्राउजर्स के लिए तेज होना चाहिए जो js फंक्शन कम () का समर्थन करते हैं और अभी भी पुराने ब्राउजर्स के साथ संगत हैं:
String.prototype.hashCode = function() {
if (Array.prototype.reduce) {
return this.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
} else {
var hash = 0, i, chr, len;
if (this.length == 0) return hash;
for (i = 0, len = this.length; i < len; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
};
उदाहरण:
my_string = 'xyz';
my_string.hashCode();
यदि आप टकराव से बचना चाहते हैं तो आप SHA-256 की तरह सुरक्षित हैश का उपयोग करना चाहते हैं । कई जावास्क्रिप्ट SHA-256 कार्यान्वयन हैं।
मैंने कई हैश कार्यान्वयनों की तुलना करने के लिए परीक्षण लिखे, https://github.com/brillout/test-javascript-hash-implementations देखें ।
या परीक्षणों को चलाने के लिए http://brillout.github.io/test-javascript-hash-implementations/ पर जाएं ।
यह कुछ अन्य उत्तरों की तुलना में थोड़ा अधिक सुरक्षित हैश होना चाहिए, लेकिन एक फ़ंक्शन में, किसी भी प्रीलोडेड स्रोत के बिना
मैंने मूल रूप से sha1 का एक छोटा सरलीकृत संस्करण बनाया ।
आप स्ट्रिंग के बाइट्स लेते हैं और उन्हें 4 से 32 बिट "शब्दों" द्वारा समूहित करते हैं
फिर हम हर 8 शब्दों को 40 शब्दों (परिणाम पर बड़े प्रभाव के लिए) तक बढ़ाते हैं।
यह हैशिंग फ़ंक्शन (अंतिम कम) पर जाता है जहां हम वर्तमान स्थिति और इनपुट के साथ कुछ गणित करते हैं। हमें हमेशा 4 शब्द मिलते हैं।
यह लगभग एक-कमांड / वन-लाइन संस्करण है जो नक्शे का उपयोग करता है, कम करता है ... लूप के बजाय, लेकिन यह अभी भी बहुत तेज है
String.prototype.hash = function(){
var rot = (word, shift) => word << shift | word >>> (32 - shift);
return unescape(encodeURIComponent(this.valueOf())).split("").map(char =>
char.charCodeAt(0)
).reduce((done, byte, idx, arr) =>
idx % 4 == 0 ? [...done, arr.slice(idx, idx + 4)] : done
, []).reduce((done, group) =>
[...done, group[0] << 24 | group[1] << 16 | group[2] << 8 | group[3]]
, []).reduce((done, word, idx, arr) =>
idx % 8 == 0 ? [...done, arr.slice(idx, idx + 8)] : done
, []).map(group => {
while(group.length < 40)
group.push(rot(group[group.length - 2] ^ group[group.length - 5] ^ group[group.length - 8], 3));
return group;
}).flat().reduce((state, word, idx, arr) => {
var temp = ((state[0] + rot(state[1], 5) + word + idx + state[3]) & 0xffffffff) ^ state[idx % 2 == 0 ? 4 : 5](state[0], state[1], state[2]);
state[0] = rot(state[1] ^ state[2], 11);
state[1] = ~state[2] ^ rot(~state[3], 19);
state[2] = rot(~state[3], 11);
state[3] = temp;
return state;
}, [0xbd173622, 0x96d8975c, 0x3a6d1a23, 0xe5843775,
(w1, w2, w3) => (w1 & rot(w2, 5)) | (~rot(w1, 11) & w3),
(w1, w2, w3) => w1 ^ rot(w2, 5) ^ rot(w3, 11)]
).slice(0, 4).map(p =>
p >>> 0
).map(word =>
("0000000" + word.toString(16)).slice(-8)
).join("");
};
हम शब्द सरणी के बजाय स्ट्रिंग प्राप्त करने के लिए आउटपुट को हेक्स में परिवर्तित करते हैं।
उपयोग सरल है। "a string".hash()
वापसी के लिए वापसी होगी"88a09e8f9cc6f8c71c4497fbb36f84cd"
मैं हेक्स स्ट्रिंग्स में परिवर्तित चार कोड का एक सरल संयोजन के लिए गया था। यह एक अपेक्षाकृत संकीर्ण उद्देश्य के रूप में कार्य करता है, अर्थात् बस एक SHORT स्ट्रिंग (जैसे शीर्षक, टैग) के हैश प्रतिनिधित्व की आवश्यकता होती है जो एक सर्वर पक्ष के साथ आदान-प्रदान किया जाता है जो प्रासंगिक कारणों के लिए आसानी से स्वीकार किए गए हैशकोड जावा पोर्ट को लागू नहीं कर सकता है। जाहिर है यहां कोई सुरक्षा आवेदन नहीं है।
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('');
}
इसे अंडरस्कोर के साथ और अधिक ट्रोल और ब्राउज़र-सहिष्णु बनाया जा सकता है। उदाहरण:
"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"
इस पद्धति के साथ स्वाभाविक रूप से टकराव का अधिक जोखिम है, हालांकि आप कम में अंकगणित के साथ बेला कर सकते हैं, हालांकि आप हैश को विविधता और लंबा करना चाहते थे।
@ Esmiralha के उत्तर का थोड़ा सरल संस्करण।
मैं इस संस्करण में स्ट्रिंग को ओवरराइड नहीं करता, क्योंकि इससे कुछ अवांछित व्यवहार हो सकता है।
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);
}
मुझे तैयार-टू-यूज़ समाधानों के बजाय इस ओवर-कॉम्प्लेक्टेड क्रिप्टो कोड का उपयोग करने का कोई कारण नहीं दिखता है, जैसे ऑब्जेक्ट-हैश लाइब्रेरी, या वेंडर पर निर्भरता अधिक उत्पादक है, समय बचाता है और रखरखाव लागत को कम करता है।
बस https://github.com/puleos/object-hash का उपयोग करें
var hash = require('object-hash');
hash({foo: 'bar'}) // => '67b69634f9880a282c14a0f0cb7ba20cf5d677e9'
hash([1, 2, 2.718, 3.14159]) // => '136b9b88375971dff9f1af09d7356e3e04281951'
var crypto = require('crypto');
। मुझे लगता है कि यह एक निर्माण के दौरान इस विक्रेता से निर्भरता कोड को न्यूनतम संस्करण में जोड़ता है।