[javascript] जावास्क्रिप्ट / jQuery में स्ट्रिंग से हैश उत्पन्न करें


Answers

संपादित करें

मेरे जेएसपीआरएफ परीक्षणों के आधार पर, स्वीकृत उत्तर वास्तव में तेज़ है: 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);              
}
Question

मुझे स्ट्रिंग को हैश के कुछ रूप में बदलने की जरूरत है। जावास्क्रिप्ट / jQuery में यह संभव है?

मैं सर्वर-साइड भाषा का उपयोग नहीं कर रहा हूं इसलिए मैं इसे इस तरह से नहीं कर सकता।




एक तेज़ और संक्षिप्त जो here से अनुकूलित किया गया था:

String.prototype.hashCode = function() {
  var hash = 5381, i = this.length
  while(i)
    hash = (hash * 33) ^ this.charCodeAt(--i)
  return hash >>> 0;
}



मैंने दो समाधान (उपयोगकर्ता एस्मिराहा और लॉर्डवॉल) को एक ऐसा फ़ंक्शन प्राप्त करने के लिए जोड़ा है जो जेएस फ़ंक्शन को कम करने वाले ब्राउज़र के लिए तेज़ होना चाहिए () और पुराने ब्राउज़रों के साथ अभी भी संगत है:

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();



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!'));




Mar10 द्वारा उदाहरण के लिए धन्यवाद, मुझे एक ही परिणाम प्राप्त करने के लिए सी # और जावास्क्रिप्ट को एक एफएनवी -1 ए के लिए एक तरीका मिला। यदि यूनिकोड वर्ण मौजूद हैं, तो प्रदर्शन के लिए ऊपरी हिस्से को त्याग दिया जाता है। पता नहीं है कि हैशिंग करते समय उन्हें बनाए रखने में मददगार क्यों होगा, क्योंकि अभी केवल हैशिंग यूआरएल पथ हैं।

सी # संस्करण

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);
}



यह एक परिष्कृत और बेहतर प्रदर्शन संस्करण है:

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() जावा के कार्यान्वयन से मेल खाता है 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;
}

का आनंद लें!




इस समाधान के साथ हम मानकों को संग्रहीत या अनुप्रयोग परतों के बीच भेजे जाने पर कुछ मुद्दों से बचने के लिए वर्ण सेट निर्दिष्ट कर सकते हैं, उदाहरण के लिए: जब परिणाम स्ट्रिंग (हैश) प्रतिशत एन्कोडिंग उत्पन्न करती है और उस स्ट्रिंग को दृश्य विधि से GET विधि का उपयोग करके नियंत्रक को भेजा जाता है परत।

function doHashCode() {
    String.prototype.hashCode = function () {
        var text = "";
        var possible = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

        for (var i = 0; i < 15; i++)
            text += possible.charAt(Math.floor(Math.random() * possible.length));
        return text;
    }

    var hash = new String().hashCode();
    $('#input-text-hash').val(hash); // your html input text

}



यदि आप टकराव से बचना चाहते हैं तो आप SHA-256 जैसे सुरक्षित हैश का उपयोग करना चाह सकते हैं। कई जावास्क्रिप्ट SHA-256 कार्यान्वयन हैं।

मैंने कई हैश कार्यान्वयन की तुलना करने के लिए परीक्षण लिखे हैं, https://github.com/brillout/test-javascript-hash-implementations

या परीक्षण चलाने के लिए http://brillout.github.io/test-javascript-hash-implementations/ पर जाएं।




Related