জাভাস্ক্রিপ্টে স্ট্রিং থেকে একটি হ্যাশ তৈরি করুন


585

আমার স্ট্রিংগুলিকে কিছুটা হ্যাশের রূপান্তর করতে হবে। এটি কি জাভাস্ক্রিপ্টে সম্ভব?

আমি একটি সার্ভার-সাইড ভাষা ব্যবহার করছি না তাই আমি সেভাবে এটি করতে পারি না।


7
MD5 সুরক্ষিত নয়, সুতরাং এটির জন্য সন্ধান করবেন না।
henrikstroem

166
@henrikstroem আপনি যা করছেন তার উপর নির্ভরশীল; নিরাপত্তাহীনতার জন্য একটি হ্যাশ তৈরি করতে এমডি 5 ব্যবহার করে কোনও সমস্যা নেই।
ব্র্যাড কোচ

7
@ ব্র্যাডকচ আপনি যা করছেন তার উপর নির্ভর করে; সুরক্ষার প্রয়োজনে এমডি 5 ব্যবহার করার জন্য কোনও ভুল নেই। পাসওয়ার্ডগুলি হ্যাশ করার জন্য অবশ্যই আরও ভাল পদ্ধতি রয়েছে তবে ইউআরএল সাইন করার মতো কাজ করার জন্য এমডি 5 ঠিক আছে।
পল ফেরেট

81
আমি মজার বিষয় মনে করি যে এখানে MD5 মন্তব্যগুলিতে সমালোচিত হলেও প্রায় সমস্ত উত্তরই হ্যাশ অ্যালগরিদমকে আরও খারাপের প্রস্তাব দেয় এবং প্রচুর পরিমাণে উন্নতি করে।
ডোমেন

38
ডাউনলোড অটুট এসেছে তা যাচাই করতে এমডি 5 ব্যবহার করে আপনার সমস্ত সহকর্মীদের কাছে আপনার পাসওয়ার্ডগুলি যাদুতে ইমেল করা যাচ্ছে না।
জেমস এম। লে

উত্তর:


788
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/


22
এটি জাভাতে একই ব্যবহৃত। hash << 5 - hashহিসাবে একই hash * 31 + charকিন্তু অনেক দ্রুত। এটি দুর্দান্ত কারণ এটি এত তাড়াতাড়ি, এবং 31 এটি একটি ছোট প্রাইম prime সেখানে জয় জিতুন।
কর্সিকা

41
আমি jsperf ( jsperf.com/hashing-strings ) এ কয়েকটি পরীক্ষা করেছি এবং বিটওয়াইস ফাংশনটি সংখ্যা ভিত্তিক ফাংশনের চেয়ে আসলে আরও ধীর।
স্কিরিট

17
@ পিটারআরনজেন্টাই কেন এটি "অব্যর্থ"? সংখ্যা-ভিত্তিক কোড (hash * 31) + charদ্বারা উত্পাদিত আউটপুটটি শিফট-ভিত্তিক কোড দ্বারা উত্পাদিত আউটপুটটির মতো ((hash<<5)-hash)+char, এমনকি খুব দীর্ঘ স্ট্রিংয়ের জন্যও (আমি এটি লক্ষ লক্ষের বেশি অক্ষরের স্ট্রিং দিয়ে পরীক্ষা করেছি), সুতরাং এটি "ব্যবহারযোগ্য" নয় নির্ভুলতার। সংখ্যাটি ভিত্তিক এবং শিফ্ট-ভিত্তিক সংস্করণ উভয়ের জন্য জটিলতাটি হ'ল (এন), সুতরাং জটিলতার ক্ষেত্রে এটি "ব্যবহারযোগ্য" নয়।
টাচায়নওয়ার্টেক্স

13
আউটপুটটির স্বতন্ত্রতা (বা না) সম্পর্কে কেউ মন্তব্য করতে পারেন? বিশেষত, যদি আমি কেবল এই হ্যাশটি দৈর্ঘ্যের চেয়ে কম স্ট্রিংয়ের জন্য ব্যবহার করি nতবে সবচেয়ে বড়টি nকোনটি যার জন্য আমি সংঘর্ষের সম্ভাবনা নাও পেতে পারি?
ডন ম্যাককুরডি

34
স্ট্রিং প্রোটোটাইপে এগুলির প্রয়োজনীয়তাগুলি (বা হওয়া উচিত) আছে কি? স্রেফ উদহার করা কি কোনও কার্যকর / দক্ষ হবে; var hashCode = function hashCode (str) {etc...}? এবং তারপর হিসাবে ব্যবহার করবেন hashCode("mystring")?
রাতের

145

সম্পাদনা

আমার 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)

3
ইতিবাচক সংখ্যাটি কি হ্যাশ পাওয়ার উপায় আছে?
প্রোস্টো ট্রেডার

45
অদ্ভুত। আমি কেবল এটি পরীক্ষা করেছি এবং এটি গৃহীত উত্তরের চেয়ে ধীর হয়ে গেছে a jsperf.com/hashcodelordvlad
লর্ডভ্লাদ

112
ভাল লোক @ লর্ডভ্ল্যাড, আসলে তার নিজের উত্তরটি পরীক্ষা করছেন এবং তারপরে ধীর হওয়ার সময় রিপোর্ট করছেন।
মাইকমেকানা

9
আমি কেবল উপলব্ধি করেছি: এটি সঠিকভাবে উপলব্ধি করে যে গ্রহণযোগ্য উত্তরটি দ্রুত, কারণ আমার সংস্করণটিকে স্ট্রিংটিকে প্রথমে অ্যারেতে পরিণত করতে হবে, নতুন মেমরি বরাদ্দ করতে হবে এবং প্রতিটি চরিত্র অনুলিপি করতে হবে ...
লর্ডভ্লাদ

5
[] .reduce.call (স্ট্রিং, (পি, সি, আই, এ) => (পি << 5) - পি + এ কোডার কোডএট (আই), 0);
ডিজ্জি

107

নোট: এমনকি সেরা 32-বিট হ্যাশ সঙ্গে, দুর্ঘটনায় হবে কখনো কখনো ঘটে থাকে।

হ্যাশের সংঘর্ষের সম্ভাব্যতা গণনা করা যেতে পারে 1 - ই ^ (-কে (কে -1) / 2 এন, হিসাবে এপ্রোক্সিমেটেড কে ^ 2/2 এন ( এখানে দেখুন )। এটি অন্তর্দৃষ্টির প্রস্তাবের চেয়ে বেশি হতে পারে:
32-বিট হ্যাশ এবং কে = 10,000 আইটেম ধরে নেওয়া, 1.2% এর সম্ভাব্যতার সাথে একটি সংঘর্ষ ঘটবে। 77,163 নমুনার জন্য সম্ভাবনা 50% হয়ে যায়! ( ক্যালকুলেটর )
আমি নীচে একটি workaround পরামর্শ।

এই প্রশ্নের উত্তরে কোন হ্যাশিং অ্যালগরিদম স্বতন্ত্রতা এবং গতির জন্য সেরা? , আয়ান বাল্ড গভীরতা বিশ্লেষণে ভাল পোস্ট করেছেন । সংক্ষেপে (আমি এটি ব্যাখ্যা হিসাবে), তিনি এই সিদ্ধান্তে পৌঁছেছেন যে মুরমুর সেরা, তারপরে এফএনভি -1 এ।
জাভার স্ট্রিং.হ্যাশকোড () এলগরিদম যে ইসমিরালাল প্রস্তাব করেছিলেন তা ডিজেবি 2 এর একটি রূপ বলে মনে হচ্ছে।

  • এফএনভি -১ এ এর ​​ডিজেবি 2 এর তুলনায় আরও ভাল বিতরণ রয়েছে, তবে এটি ধীরে ধীরে
  • ডিজেবি 2 এফএনভি -1 এ এর ​​চেয়ে দ্রুত, তবে আরও সংঘর্ষের প্রবণতা রয়েছে
  • মারজুরহ্যাশ 3 ডিজেবি 2 এবং এফএনভি -1 এ এর ​​চেয়ে ভাল এবং দ্রুত (তবে অনুকূলিত বাস্তবায়নের জন্য এফএনভি এবং ডিজেবি 2 এর চেয়ে বেশি কোডের লাইন প্রয়োজন)

বড় ইনপুট স্ট্রিং এখানে কিছু benchmarks: http://jsperf.com/32-bit-hash
যখন ছোট ইনপুট স্ট্রিং কুচি-কুচি করিয়া কাটা বস্তু হয়, কলকল এর পারফরম্যান্সের ঝরিয়া, DJ2B এবং FNV-1A আপেক্ষিক: http://jsperf.com/32- বিট-হ্যাশ / 3

তাই সাধারণভাবে আমি বচসা করার পরামর্শ দিই।
একটি জাভাস্ক্রিপ্ট বাস্তবায়ন জন্য এখানে দেখুন: 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)?
ম্যানুয়েল মিউরার

3
এটি '0 এর শীর্ষস্থানীয় যোগ করে যাতে ফলস্বরূপ হ্যাশটি সর্বদা 8 অক্ষর দীর্ঘ হয়। আউটপুটগুলিতে পড়তে এবং সনাক্ত করা সহজ তবে এটি আমার ব্যক্তিগত মতামত
mar10

আহ ঠিক আছে, আমি পেয়েছি ছোট জন্য hval, (hval >>> 0).toString(16)8 টিরও কম অক্ষর হতে পারে, তাই আপনি এটিকে জিরো দিয়ে প্যাড করুন। আমি কেবল বিভ্রান্ত হয়ে পড়েছিলাম কারণ (hval >>> 0).toString(16)সর্বদা আমার জন্য ঠিক 8 টি চরিত্রের স্ট্রিং ছিল।
ম্যানুয়েল মিউরার

3
আমি এই উত্তরটি পছন্দ করি কারণ এটি একটি সুও আরও ভাল বিতরণ হ্যাশ উত্পাদন করে: এখানে প্রস্তাবিত অন্যান্য কার্যগুলি ফলস্বরূপ হ্যাশ মান তৈরি করবে। উদাহরণস্বরূপ `হ্যাশ (" উদাহরণ 1 ") - হ্যাশ (" উদাহরণ 2 ") == 1", যদিও এটি
এককটি

1
"FNV-1a এর জবাবে DJB2 এর তুলনায় এএ আরও ভাল বিতরণ হয়েছে, তবে ধীর গতিতে" - আমি মনে করি যে ES6 Math.imulফাংশনটি ব্যবহার করে প্রয়োগ করা হয় তখন FNV1a অত্যন্ত দ্রুত হতে পারে বলে মনে করা উচিত । এটি একাই শীর্ষস্থানীয় মানদণ্ড তৈরি করে এবং শেষ পর্যন্ত ডিজেবি 2 এর চেয়ে ভাল পছন্দ।
bryc

65

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

সম্পাদনা (2019-11-04) :

এক-লাইন তীর ফাংশন সংস্করণ:

const hashCode = s => s.split('').reduce((a,b) => (((a << 5) - a) + b.charCodeAt(0))|0, 0)

// test
console.log(hashCode('Hello!'))


1
ভাগ করার জন্য ধন্যবাদ str += ""হ্যাশিংয়ের আগে আমি ব্যতিক্রমগুলি এড়ানোর জন্য যুক্ত করেছিলাম str.split is not a functionযখন নন-স্ট্রিংগুলি প্যারামিটার হিসাবে পাস করা হয়েছিল
বিটলজুইস

4
তবে অনেকগুলি, এর যে
কোনওটির

আমি এও লক্ষ্য করেছি যে দ্রুততম "রেট্রো" সমাধানটি যদি আপনি লাইন ফিডগুলি সরিয়ে ফেলেন তবে এটি কেবল 3 লাইন দীর্ঘ।
অ্যান্ডিও

2
এই উত্পাদন করার কোনও উপায় কেবল ইতিবাচক তবে এখনও অনন্য ফলাফল?
Dids

3
@deekshith গৃহীত উত্তরগুলি hash |= 032 বিট ইন্টিতে রূপান্তর করতে ব্যবহার করে। এই বাস্তবায়ন হয় না। এটি কি বাগ?
সুকিমা

48

প্রায় অর্ধেক উত্তর জাভা এর বাস্তবায়ন 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}

উপায়টি অতিক্রম করার সাথে , এখানে আরও ভাল কিছু রয়েছে — সাইরব ৫৩, একটি সাধারণ তবে উচ্চ মানের 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);
};

সুপরিচিত মার্মুরহ্যাশ / এক্সএক্সএইচএস অ্যালগরিদমগুলির অনুরূপ, এটি গুণ এবং জর্শিফ্টের সংমিশ্রণ ব্যবহার করে হ্যাশ উত্পন্ন করতে করে, তবে নয়। ফলস্বরূপ এটি জাভাস্ক্রিপ্টের যে কোনওটির চেয়ে দ্রুত এবং কার্যকরভাবে কার্যকর করা সহজ simp

এটি হিমস্রোঞ্চ (অ-কঠোর) অর্জন করে, যার মূলত ইনপুটটির ছোট ছোট পরিবর্তনগুলির ফলে আউটপুটে বড় পরিবর্তন হয়, ফলে হ্যাশটি এলোমেলোভাবে প্রদর্শিত হয়:

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-বিট পূর্ণসংখ্যার মধ্যে সীমাবদ্ধ। প্রয়োজনে সম্পূর্ণ -৪-বিট আউটপুট ব্যবহার করা যেতে পারে হেক্স স্ট্রিং বা অ্যারের জন্য রিটার্ন লাইনে পরিবর্তন করে করা ।

সচেতন থাকুন যে হেক্স স্ট্রিংগুলি তৈরি করা কর্মক্ষমতা-সংকটজনক পরিস্থিতিতে ব্যাচ প্রসেসিংয়ে মারাত্মকভাবে ধীর করতে পারে।

return (h2>>>0).toString(16).padStart(8,0)+(h1>>>0).toString(16).padStart(8,0);
// or
return [h2>>>0, h1>>>0];

এবং কেবল মজাদার জন্য, এখানে এফএনভি বা ডিজেবি 2 এর চেয়ে উচ্চ মানের সহ 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}

4
বাহ, এটি সংক্ষিপ্ত (বা অনুরূপ) ইনপুটগুলির জন্য স্বাভাবিক * 31 একের চেয়ে অনেক বেশি ভাল। :)
lapo

2
কোথায় শুরু করা chহয়?
hellowill89

3
@ হেলিওল ৮৯ ওয়াও, আমি এটি ঘোষণা করতে ভুলে গিয়েছিলাম এবং বিশ্বব্যাপী ক্ষয়ক্ষতিতে রক্তক্ষরণ হয়েছিল। এখনই ঠিক হয়েছে, ধন্যবাদ: ')
ব্রাইক

আইই 11 এর জন্য ব্যর্থ: বস্তু সম্পত্তি বা পদ্ধতি সমর্থন করে না 'imul'
বাচটি

2
@ বাচটি আপনি পলিফিল বা একটি পূর্ণ ES6 শিম ব্যবহার করতে পারেন । তবে আইই 11 এলোমেলোভাবে 2009 সালে কোনও আপডেট ছাড়াই হিমশীতল।
bryc

28

যদি এটি কাউকে সহায়তা করে তবে আমি শীর্ষ দুটি উত্তর একটি পুরানো ব্রাউজার-সহনশীল সংস্করণে সংযুক্ত করেছি, যা 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; }
মুসাকখির সাইয়েদ

26

এটি একটি পরিশ্রুত এবং আরও ভাল পারফর্মিং বৈকল্পিক:

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

উপভোগ করুন!


2
দুর্দান্ত উত্তর, তবে << 0 এর উদ্দেশ্য কী?
কুলাং

8
@koolaang বাম বিষ্ঠা অপারেটর আছে, developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
MMM

29
@ মোমোমো মানে বাম শিফট ?
ডাব্লুএইচডি

2
@ মোমো আমার মনে হয় তিনি জিজ্ঞাসা করছিলেন কেন এটি শূন্য বিটের বাম শিফ্ট।
jpfx1342

3
@ মায়াকন (2 ^ 32 - 1)
নিজরাজ গেলানী

24

আমি কিছুটা অবাক হয়েছি কেউই নতুন সাবলেটক্রিপ্টো এপিআই সম্পর্কে এখনও কথা বলেনি

স্ট্রিং থেকে একটি হ্যাশ পেতে, আপনি এই 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);
  });


4
আমি রাজী. 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('')); });
হেক্সে

3
স্ট্রিংগুলির জন্য একটি ক্রিপ্টোগ্রাফিক হ্যাশ ফাংশনটি কিছুটা ওভারকিল .. cryptoহুবহু পারফরম্যান্ট নয়।
bryc

পরীক্ষামূলকভাবে চলমান, অন্তর্নির্মিত (কোনও কাস্টম প্রয়োগের প্রয়োজন নেই), বীজযোগ্য, এবং আমার কেবল একটি গেমের মানচিত্র তৈরির জন্য কয়েকশ সংখ্যক সংখ্যার প্রয়োজন ছিল, নির্ভরযোগ্য মানের মানের এলোমেলো this তবে দেখা যাচ্ছে যে এটি সিঙ্ক্রোনালিভাবে করার কোনও উপায় নেই। প্রতিবার আপনি আপনার বীজযুক্ত এলোমেলো ইঞ্জিন বললে কিছু অ্যাসিঙ্ক কলব্যাক জিনিসযুক্ত সরবরাহ করা কোডটি দুর্দান্ত অ वाचনীয় করে তোলে এবং হাস্যকর দেখায়। : আমি না এই ন্যক্কারজনক crypto.subtle ইন্টারফেস নিয়ে এসেছেন পেতে পারি, তাই আমি শেষ পর্যন্ত আমি এই উত্তর থেকে xmur3 + + sfc32 যেতে হয়েছে stackoverflow.com/a/47593316/1201863
লুক

7

মার্চ 10 দ্বারা উদাহরণের জন্য ধন্যবাদ, আমি এফএনভি -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);
}

@ মথিআসআরউ ইউনিকোড অক্ষরগুলির পক্ষে মেমরির 8 বিট অতিক্রম করা সম্ভব, তাই আমি ধরে নিচ্ছি 0xFF কেবলমাত্র এই সীমার বাইরে যেকোন কিছুই বন্ধ করে দেয়। এখানে CharCodeAt () সম্পর্কে আরও দেখুন: বিকাশকারী.মোজিলা.আর.ইন.ইউএস
ডকস / ওয়েব

যদি ES6 উপলভ্য থাকে (সমস্ত আধুনিক ইঞ্জিনগুলি এটি সমর্থন করে), Math.imulগুণনের পদক্ষেপের জন্য ব্যবহার করা যেতে পারে, যা কর্মক্ষমতা ব্যাপকভাবে উন্নত করে । কেবল ইস্যুটি হ'ল এটি শিম ছাড়া আইই 11 এ কাজ করবে না ।
ব্রাইক

6

একটি দ্রুত এবং সংক্ষিপ্ততর যা এখান থেকে রূপান্তরিত হয়েছিল :

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

5

ব্যবহারকারীর নাম এবং বর্তমান সময়ের উপর ভিত্তি করে একটি অনন্য-আইশ আইডি উত্পন্ন করতে আমার অনুরূপ ফাংশন (তবে ভিন্ন) প্রয়োজন। তাই:

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


2
@ t0r0X ভালভাবে এখন আমি শর্টিড নামে একটি মডিউল ব্যবহার করি: npmjs.com/package/shortid
jcollum

1
আপনি কীভাবে সংক্ষিপ্ত ব্যবহারকারীর নাম ব্যবহার করছেন? এটি কেবল আইডিগুলি তৈরি করে বলে মনে হচ্ছে তবে আপনি দেখতে পাচ্ছেন না আপনি কীভাবে একটি স্ট্রিং থেকে একটি হ্যাশ তৈরি করতে ব্যবহার করছেন
সাইবারওয়ম্ব্যাট

1
এই উত্তরের 3 টি ডাউনভোট রয়েছে। আমার জীবনের জন্য আমি কল্পনা করতে পারি না কেন। কেউ কিছু বলেনি ...: - /
jcollum

1
@ জোকলুম সে কারণেই আমি প্রায় কোনওভাবেই বাসি প্রশ্নের উত্তর দিই না .. হিট এবং রানগুলি নজরে না পড়ে। আপনি উত্তরটি ঠিক করার পরেও কেউ এর ভারসাম্য বজায় রাখতে আসে না।
bryc

5

আমার দ্রুত (খুব দীর্ঘ) এক লাইনার এফএনভির Multiply+Xorপদ্ধতির ভিত্তিতে :

my_string.split('').map(v=>v.charCodeAt(0)).reduce((a,v)=>a+((a<<7)+(a<<3))^v).toString(16);

5

SubtleCrypto.digest

আমি একটি সার্ভার-সাইড ভাষা ব্যবহার করছি না তাই আমি সেভাবে এটি করতে পারি না।

আপনি কি নিশ্চিত যে আপনি সেভাবে এটি করতে পারবেন না ?

আপনি কি ভুলে গেছেন যে আপনি জাভাস্ক্রিপ্ট ব্যবহার করছেন, ভাষাটি চির-বিবর্তিত?

ব্যবহার করে দেখুন 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.")));
})();


আপনার দু'বছর আগে কাইদোর উত্তর থেকে এটি কীভাবে আলাদা ?
লু

@ লুক এটি আপাতদৃষ্টিতে নয়।
Ван Ван

3

আমি পার্টিতে দেরি করছি, তবে আপনি এই মডিউলটি ব্যবহার করতে পারেন: ক্রিপ্টো :

const crypto = require('crypto');

const SALT = '$ome$alt';

function generateHash(pass) {
  return crypto.createHmac('sha256', SALT)
    .update(pass)
    .digest('hex');
}

এই ফাংশনের ফলাফল সর্বদা 64অক্ষরের স্ট্রিং; এটার মতো কিছু:"aa54e7563b1964037849528e7ba068eb7767b1fab74a8d80fe300828b996714a"


2

আমি দুটি সমাধান (ব্যবহারকারী এসমিরালহা এবং লর্ডভ্ল্যাড) একত্রিত করে একটি ফাংশন পেতে যা ব্রাউজারগুলির জন্য দ্রুত হওয়া উচিত যা জেএস ফাংশনকে হ্রাস করে () এবং এখনও পুরানো ব্রাউজারগুলির সাথে সামঞ্জস্যপূর্ণ:

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

2

আপনি যদি সংঘর্ষ এড়াতে চান তবে আপনি SHA-256 এর মতো সুরক্ষিত হ্যাশ ব্যবহার করতে পারেন । বেশ কয়েকটি জাভাস্ক্রিপ্ট SHA-256 বাস্তবায়ন রয়েছে।

আমি বেশ কয়েকটি হ্যাশ বাস্তবায়নের তুলনা করার জন্য পরীক্ষাগুলি লিখেছিলাম, https://github.com/brillout/test-javascript-hash-implementations দেখুন

বা পরীক্ষা চালানোর জন্য http://brillout.github.io/test-javascript-hash-implementations/ এ যান ।


1
একটি সুরক্ষিত ক্রিপ্টোগ্রাফিক হ্যাশ ব্যবহার অত্যন্ত ধীর হতে পারে। সংঘর্ষ এড়ানো এট বিট প্রস্থের পণ্য, সুরক্ষা নয় is 128 বিট নন-ক্রিপ্টোগ্রাফিক হ্যাশ বা এমনকি 64 বিট বেশিরভাগ কারণে পর্যাপ্ত পরিমাণে হওয়া উচিত। মার্মুরহ্যাশ3_x86_128 বেশ দ্রুত এবং সংঘর্ষের খুব কম সম্ভাবনা রয়েছে।
bryc

2

এটি অন্য কয়েকটি উত্তরের চেয়ে কিছুটা বেশি সুরক্ষিত হ্যাশ হওয়া উচিত তবে কোনও ফাংশনে কোনও প্রিলোডেড উত্স ছাড়াই

আমি 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"


1

আমি চার্জ কোডগুলিকে হেক্স স্ট্রিংয়ে রূপান্তরিত করে একটি সাধারণ কনটেন্টেশনে গিয়েছিলাম। এটি একটি অপেক্ষাকৃত সংকীর্ণ উদ্দেশ্যে পরিবেশন করে, যেমন একটি সার্ভারের সাথে বিনিময় করার জন্য কেবল একটি শর্ট স্ট্রিংয়ের (যেমন শিরোনাম, ট্যাগ) একটি হ্যাশ প্রতিনিধিত্ব প্রয়োজন যা প্রাসঙ্গিক কারণে স্বীকৃত হ্যাশকোড জাভা বন্দর সহজেই প্রয়োগ করতে পারে না। স্পষ্টতই এখানে কোনও সুরক্ষা আবেদন নেই।

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

এটিকে আরও কড়া এবং ব্রাউজার-সহিষ্ণু করা যায় ইনডকোরের সাথে with উদাহরণ:

"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"

প্রাকৃতিকভাবে এই পদ্ধতির সাথে সংঘর্ষের ঝুঁকি, যদিও আপনি হ্রাসগুলিতে পাটিগণিতের সাথে ঝাঁকুনি খেতে পারেন তবে আপনি হ্যাশকে বৈচিত্র্যময় এবং দীর্ঘ করতে চেয়েছিলেন।


1

@ এসমিরালার উত্তরের সামান্য সরল সংস্করণ।

আমি এই সংস্করণে স্ট্রিংকে ওভাররাইড করি না, যেহেতু এর ফলে কিছু অযাচিত আচরণ হতে পারে।

function hashCode(str) {
    var hash = 0;
    for (var i = 0; i < str.length; i++) {
        hash = ~~(((hash << 5) - hash) + str.charCodeAt(i));
    }
    return hash;
}

1

এটি যুক্ত করা হচ্ছে কারণ এখনও কেউ করেনি, এবং এটি হ্যাশগুলির সাহায্যে চাওয়া এবং প্রচুর প্রয়োগ করা হয়েছে বলে মনে হয় তবে এটি সর্বদা খুব খারাপভাবে করা হয় ...

এটি একটি স্ট্রিং ইনপুট নেয় এবং সর্বাধিক সংখ্যক আপনি হ্যাশটি সমান করতে চান এবং স্ট্রিং ইনপুটটির ভিত্তিতে একটি অনন্য সংখ্যা তৈরি করে।

আপনি ইমেজগুলির একটি অ্যারেতে একটি অনন্য সূচক তৈরি করতে এটি ব্যবহার করতে পারেন (যদি আপনি কোনও ব্যবহারকারীর জন্য নির্দিষ্ট অবতারটি এড়াতে চান, তবে এলোমেলোভাবে বেছে নেওয়া হয়েছে, তবে তাদের নামের উপর ভিত্তি করেও বেছে নেওয়া হয়েছে, তাই এটি সর্বদা সেই নামটির সাথে কারও কাছে নিযুক্ত করা হবে) )।

কারও নামের উপর ভিত্তি করে অনন্য অবতার পটভূমির রঙ উত্পন্ন করার জন্য আপনি এটি অবশ্যই রঙের অ্যারেতে কোনও সূচককে ফেরত দিতে ব্যবহার করতে পারেন।

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

-1

অবজেক্ট-হ্যাশ লাইব্রেরি ইত্যাদির মতো ব্যবহারযোগ্য প্রস্তুত সমাধানের পরিবর্তে এই অতি-জটিল জটিল ক্রিপ্টো কোড ব্যবহার করার কোনও কারণ আমি দেখতে পাচ্ছি না, যেমন বিক্রেতার উপর নির্ভর করা আরও উত্পাদনশীল, সময় সাশ্রয় করে এবং রক্ষণাবেক্ষণ ব্যয় হ্রাস করে।

কেবল https://github.com/puleos/object-hash ব্যবহার করুন

var hash = require('object-hash');

hash({foo: 'bar'}) // => '67b69634f9880a282c14a0f0cb7ba20cf5d677e9'
hash([1, 2, 2.718, 3.14159]) // => '136b9b88375971dff9f1af09d7356e3e04281951'

এই lib এর উত্স কোডটি এমনকি পঠনযোগ্য নয় .. Minified কোডের কেবল 50k।
bryc

1
@ ব্রাইক যেভাবে বিক্রেতার কোডটির মতো দেখাচ্ছে বলে মনে হয় :) এবং উত্সগুলির জন্য আপনি github.com/puleos/object-hash/blob/master/index.js
ওলেগ আব্রাজাইভ

মিনিফাইড কোডটি 35.4 কেবি, পুরো উত্সটি 14.2 কেবি? ওটা কোন অর্থ প্রকাশ করে না.
bryc

2
@ ব্রাইক আপনি এই লাইনটি বিবেচনা করেছেন? var crypto = require('crypto');। আমি মনে করি এটি কোনও বিল্ড চলাকালীন সংশোধিত সংস্করণে বিক্রেতা থেকে এই নির্ভরতা কোডটি যুক্ত করে।
ওলেগ আব্রাজাইভ

আপনার যদি সত্যই অবজেক্টগুলিতে হ্যাশ দরকার হয়, আমি বাছাইকৃত কীগুলির সাথে যে কোনও অবজেক্টকে সিরিয়াল করতে কোনও সিরিয়াল লিখলাম , তারপরে বেস 36 হ্যাশ উত্পন্ন করার জন্য সাইরবি 53।
পোলভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.