জাভাস্ক্রিপ্টে কি কোনও ধরণের হ্যাশ কোড ফাংশন রয়েছে?


150

মূলত, আমি অনন্য বস্তুর একটি সেট তৈরি করার চেষ্টা করছি, একটি সেট। আমার কাছে সম্পত্তির নামের জন্য একটি জাভাস্ক্রিপ্ট অবজেক্ট ব্যবহার করার উজ্জ্বল ধারণা ছিল। যেমন,

set[obj] = true;

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


32
সমস্ত 'হ্যাশ' একই মানের মানের কারণগুলি হ'ল আপনি তাদের স্ট্রিং পদ্ধতিগুলিকে ওভাররাইড করেন নি। যেহেতু কীগুলি স্ট্রিং হওয়া আবশ্যক, তাই tostring পদ্ধতিটি একটি বৈধ কী পেতে স্বয়ংক্রিয়ভাবে কল করা হয় যাতে আপনার সমস্ত বস্তু একই ডিফল্ট স্ট্রিংয়ে রূপান্তরিত হয়: "[অবজেক্ট অবজেক্ট]"।
অ্যালানিং

4
JSON.stringify(obj)বা obj.toSource()সমস্যা এবং লক্ষ্য প্ল্যাটফর্মের উপর নির্ভর করে আপনার জন্য কাজ করতে পারে।
আনানফায়

4
@ অন্নান জেএসওএন। স্ট্রিংফাইটি (আপত্তি) আক্ষরিকভাবে পুরো (পুরো) বস্তুকে একটি স্ট্রিংয়ে রূপান্তরিত করে। সুতরাং আপনি মূলত কেবল নিজের উপর বস্তু অনুলিপি করা হবে। এটি অর্থহীন, স্থানের অপচয় এবং অনুকূল নয়।
ধাতব ঝড়

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

@ অন্নান, toSourceক্রোম
বিটিডব্লিউ

উত্তর:


35

জাভাস্ক্রিপ্ট অবজেক্টগুলি কেবল কী হিসাবে স্ট্রিং ব্যবহার করতে পারে (অন্য কোনও কিছু স্ট্রিংয়ে রূপান্তরিত হয়)।

আপনি, বিকল্পভাবে, কোনও অ্যারে বজায় রাখতে পারেন যা প্রশ্নে থাকা বস্তুগুলিকে সূচক করে এবং অবজেক্টের রেফারেন্স হিসাবে এর সূচক স্ট্রিংটি ব্যবহার করতে পারে। এটার মতো কিছু:

var ObjectReference = [];
ObjectReference.push(obj);

set['ObjectReference.' + ObjectReference.indexOf(obj)] = true;

স্পষ্টতই এটি সামান্য ভারবোজ, তবে আপনি কয়েকটি পদ্ধতি লিখতে পারেন যা এটিকে পরিচালনা করে এবং সমস্ত উইলির নিলি সেট করে।

সম্পাদনা:

আপনার অনুমানটি সত্য - এটি জাভাস্ক্রিপ্টে সংজ্ঞায়িত আচরণ - বিশেষত একটি টুস্ট্রিং রূপান্তর ঘটে এর অর্থ আপনি সম্পত্তিটির নাম হিসাবে ব্যবহৃত হবে এমন কোনও বস্তুতে নিজের নিজস্ব স্ট্রিং ফাংশনটি সংজ্ঞায়িত করতে পারেন। - ওলিজেজ

এটি আরও একটি আকর্ষণীয় বিষয় নিয়ে আসে; আপনি যে জিনিসগুলিতে হ্যাশ করতে চান তার উপর আপনি একটি স্ট্রিং পদ্ধতিটি সংজ্ঞায়িত করতে পারেন এবং এটি তাদের হ্যাশ সনাক্তকারী তৈরি করতে পারে।


অন্য বিকল্পটি হ্যাশ হিসাবে প্রতিটি বস্তুকে একটি এলোমেলো মান প্রদান করবে - সম্ভবত একটি এলোমেলো সংখ্যা + মোট টিকস - তারপরে অ্যারে থেকে অবজেক্টটি যুক্ত / সরিয়ে ফেলতে ফাংশনের একটি সেট থাকবে।
সুগেন্দ্রান

4
যদি আপনি একই জিনিস দুটিবার যোগ করেন তবে এটি ব্যর্থ হবে। এটি ভাববে যে এটি ভিন্ন।
ড্যানিয়েল এক্স মুর

"আপনি যদি একই বস্তুকে দু'বার যুক্ত করেন তবে এটি ব্যর্থ হবে It মনে হবে এটি আলাদা" " ভাল যুক্তি. একটি সমাধান হ'ল অবজেক্ট রেফারেন্সির জন্য অ্যারে সাবক্লাস হতে পারে, পুশ () এ একটি সদৃশ চেক হুক করে। এই সমাধানটির জন্য এখনই আমার সম্পাদনা করার সময় নেই তবে আমি আশা করি আমি এটি পরে মনে করব।
চোখের পলকহীনতা

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

35
আপনি যদি একবার অ্যারের লিনিয়ার স্ক্যানের প্রয়োজন হয় তবে যদি বস্তুগুলি হ্যাশ করার বিষয়টি কী?
বোর্দাইগর্ল

57

আপনি যদি জাভাস্ক্রিপ্টে জাভার মতো হ্যাশকোড () ফাংশন চান তবে তা আপনার:

String.prototype.hashCode = function(){
    var hash = 0;
    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;
}

এটি জাভাতে প্রয়োগের উপায় (বিটওয়াইস অপারেটর)।

দয়া করে নোট করুন যে হ্যাশকোডটি ইতিবাচক এবং নেতিবাচক হতে পারে, এবং এটাই স্বাভাবিক, হ্যাশকোড নেতিবাচক মান প্রদান করে দেখুন । সুতরাং, আপনি Math.abs()এই ফাংশন সহ ব্যবহার করতে বিবেচনা করতে পারে ।


5
এটি তৈরি করে
হ্যাশ

2
@ কিমখা জেএস- charএ সংরক্ষিত শব্দ এবং এতে কিছু সমস্যা হতে পারে। আরও কিছু নাম ভাল হবে।
szeryf

16
@ কোডেনিনজা বলেছেন কে? আমি এই প্রথম এমন দাবি শুনলাম। আপনি কিছু উত্স লিঙ্ক করতে পারেন? হ্যাশগুলি সাধারণত স্থির আকারের পূর্ণসংখ্যার গাণিতিক এবং বিট ক্রিয়াকলাপগুলি ব্যবহার করে গণনা করা হয়, সুতরাং ইতিবাচক বা নেতিবাচক ফলাফল পাওয়া প্রত্যাশিত something
szeryf

7
পিকি, তবে ... "যদি (এই দৈর্ঘ্য == 0) হ্যাশ ফিরে আসে;" অপ্রয়োজনীয় :) এবং ব্যক্তিগতভাবে "চরিত্র" কে "কোড" এ পরিবর্তন করবে।
ধাতব ঝড়

10
@ কোডেনিনজা এবং @ সিজারিফ: আপনি কীভাবে এটি ব্যবহার করবেন সে সম্পর্কে আপনাকে অবশ্যই যত্নবান হতে হবে। উদাহরণস্বরূপ, আমি 20 টি উপাদান সহ pickOne["helloo".hashCode() % 20]একটি অ্যারের জন্য করার চেষ্টা করেছি pickOne। আমি পেয়েছি undefinedকারণ হ্যাশ কোডটি নেতিবাচক, সুতরাং এটি একটি উদাহরণ যেখানে কোনও (আমাকে) সুস্পষ্টভাবে ইতিবাচক হ্যাশ কোডগুলি ধরে নিয়েছিল ।
জিম পিভারস্কি

31

এটি করার সহজতম উপায় হ'ল আপনার প্রতিটি বস্তুর নিজস্ব অনন্য toStringপদ্ধতি:

(function() {
    var id = 0;

    /*global MyObject */
    MyObject = function() {
        this.objectId = '<#MyObject:' + (id++) + '>';
        this.toString= function() {
            return this.objectId;
        };
    };
})();

আমার একই সমস্যা ছিল এবং এটি আমার পক্ষে ন্যূনতম গোলযোগের সাথে পুরোপুরি সমাধান করেছিল এবং এটি অনেক সহজ ছিল যে কিছু ফ্যাটি জাভা শৈলীর পুনরায় বাস্তবায়ন করা এবং আপনার অবজেক্ট ক্লাসগুলিতে Hashtableযুক্ত করা equals()এবং hashCode()। কেবল নিশ্চিত হয়ে নিন যে আপনি নিজের হ্যাশটিতে '<# MyObject: 12>' স্ট্রিংটিও আটকেছেন না বা এটি সেই আইডির সাহায্যে আপনার বহির্গমন অবজেক্টের জন্য এন্ট্রি মুছে ফেলবে।

এখন আমার সমস্ত হ্যাশ সম্পূর্ণ শীতল। আমি এই সঠিক বিষয়টি সম্পর্কে কিছুদিন আগে একটি ব্লগ এন্ট্রি পোস্ট করেছি ।


28
তবে এটি পুরো বিষয়টি মিস করে। জাভা আছে equals()এবং hashCode()যাতে দুটি সমতুল্য বস্তুর একই হ্যাশ মান হয়। উপরোক্ত পদ্ধতিটি ব্যবহার করার অর্থ হ'ল প্রতিটি ঘটনার MyObjectএকটি অনন্য স্ট্রিং থাকবে যার অর্থ আপনাকে মানচিত্র থেকে সঠিক মান পুনরুদ্ধার করতে সর্বদা সেই বস্তুর একটি রেফারেন্স রাখতে হবে। একটি কী থাকা অর্থহীন, কারণ এটি কোনও বিষয়ের স্বতন্ত্রতার সাথে কোনও সম্পর্ক রাখে না। toString()আপনি কী হিসাবে নির্দিষ্ট ধরণের অবজেক্টটি ব্যবহার করছেন তার জন্য একটি কার্যকর ফাংশন কার্যকর করা দরকার।
সেথ্রো

@ সেথ্রো আপনি toStringঅবজেক্টগুলির জন্য এটি বাস্তবায়ন করতে পারেন যে এটি সরাসরি একটি সমতুল্য সম্পর্কের মানচিত্র করে যাতে দুটি বস্তু একই স্ট্রিং তৈরি করে যদি তারা "সমান" হিসাবে বিবেচিত হয়।
ড্যানিয়েল এক্স মুর

3
ঠিক, এবং এটি হ'ল একমাত্র সঠিক উপায় toString()যা আপনাকে একটি Objectহিসাবে ব্যবহার করার অনুমতি দেয় Set। আমি মনে করি যে আমি আপনার জবাবকে ভুল ভিত্তিতে বুঝেছি কেস ভিত্তিতে কেস এর toString()সমতুল্য equals()বা এড়িয়ে যাওয়া এড়াতে জেনেরিক সমাধান সরবরাহ করার চেষ্টা করেছি hashCode()
সেথ্রো

3
Dowvoted। এই কি একটি হ্যাশকোড হয়, আমার উত্তরগুলি দেখতে নয় stackoverflow.com/a/14953738/524126 : আর হ্যাশকোড প্রকৃত বাস্তবায়ন stackoverflow.com/a/15868654/524126
Metalstorm

5
@ মেটালস্টর্ম প্রশ্নটি একটি "সত্য" হ্যাশকোড সম্পর্কে জিজ্ঞাসা করছিল না, বরং জাভাস্ক্রিপ্টে সেট হিসাবে কোনও অবজেক্টটিকে সফলভাবে কীভাবে ব্যবহার করা যায়।
ড্যানিয়েল এক্স মুর

20

আপনি যা বর্ণনা করেছেন তা হ্যাকমনি উইকম্যাপস , ECMAScript 6 স্পেসিফিকেশনের অংশ (জাভাস্ক্রিপ্টের পরবর্তী সংস্করণ) দ্বারা আচ্ছাদিত । এটি: একটি সেট যেখানে কীগুলি কোনও কিছু (অপরিজ্ঞাত সহ) হতে পারে এবং অণনীয়।

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

এমডিএন থেকে :

var wm1 = new WeakMap(),
    wm2 = new WeakMap();
var o1 = {},
    o2 = function(){},
    o3 = window;

wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // A value can be anything, including an object or a function.
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // Keys and values can be any objects. Even WeakMaps!

wm1.get(o2); // "azerty"
wm2.get(o2); // Undefined, because there is no value for o2 on wm2.
wm2.get(o3); // Undefined, because that is the set value.

wm1.has(o2); // True
wm2.has(o2); // False
wm2.has(o3); // True (even if the value itself is 'undefined').

wm1.has(o1);   // True
wm1.delete(o1);
wm1.has(o1);   // False

WeakMaps বর্তমান ফায়ারফক্স, ক্রোম এবং এজ এ উপলব্ধ। এগুলি নোড ভি 7 এবং --harmony-weak-mapsপতাকা সহ v6 এ সমর্থিত ।


1
এই এবং এর মধ্যে পার্থক্য কি Map?
smac89

@ smac89 WeakMap এর সীমাবদ্ধতা রয়েছে: 1) কেবলমাত্র বস্তুকে কী হিসাবে গ্রহণ করে 2) কোনও আকারের সম্পত্তি নেই 3) কোনও পুনরুক্তিকারী বা forEach পদ্ধতি 4) কোনও পরিষ্কার পদ্ধতি নেই। কী অবজেক্ট - সুতরাং যখন বস্তুটি মেমরি থেকে মুছে ফেলা হবে - এই বস্তুর সাথে সংযুক্ত WeakMap থেকে ডেটাও মুছে ফেলা হবে। এটি খুব কার্যকর যখন আমরা তথ্য রাখতে চাই, যা কেবলমাত্র বস্তুর অস্তিত্বের সময় উপস্থিত থাকতে পারে। সুতরাং উইকম্যাপের কেবলমাত্র পদ্ধতি রয়েছে: লেখার জন্য মুছুন, মুছুন, পড়ুন
একেতেরিনা টোকারেভা

এটি ঠিক মতো কাজ করে না ... var m = new Map();m.set({},"abc"); console.log(m.get({}) //=>undefinedএটি কেবলমাত্র যদি আপনার একই ভেরিয়েবলটি সেট কমান্ডে মূলত উল্লেখ করা হয় তবে এটি কাজ করে। ইজিvar m = new Map();a={};m.set(a,"abc"); console.log(m.get(a) //=>undefined
সানকারন

1
@ সানকারন এটি একই ভেরিয়েবল হতে হবে না, তবে তাদের একই জিনিসকে নির্দেশ করতে হবে। আপনার প্রথম উদাহরণে আপনার দুটি পৃথক বস্তু রয়েছে, সেগুলি দেখতে একই রকম, তবে তাদের আলাদা ঠিকানা রয়েছে।
Svish

1
@ স্পিশ ভাল জায়গা! যদিও আমি এখনই এটি জানি, তবে আমি সম্ভবত এটি আর করতে পারি না :)
সানকারন

19

আমি যে সমাধানটি বেছে নিয়েছি তা ড্যানিয়েলের অনুরূপ, তবে কোনও অবজেক্ট ফ্যাক্টরি ব্যবহার না করে টসস্ট্রিংকে ওভাররাইড করার পরিবর্তে আমি হ্যাশটিকে বস্তুটিতে স্পষ্টভাবে যুক্ত করব যখন এটি একটি getHashCode ফাংশনের মাধ্যমে প্রথমে অনুরোধ করা হয়েছিল। একটু অগোছালো, তবে আমার প্রয়োজনের জন্য আরও ভাল :)

Function.prototype.getHashCode = (function(id) {
    return function() {
        if (!this.hashCode) {
            this.hashCode = '<hash|#' + (id++) + '>';
        }
        return this.hashCode;
    }
}(0));

7
আপনি এই পথে যেতে চান, এটা মাধ্যমে হ্যাশকোড সেট করতে অনেক ভালো Object.definePropertyসঙ্গে enumerableসেট false, তাই যদি আপনি কোন বিপর্যস্ত করা হবে না for .. inলুপ।
সেবাস্তিয়ান নওক 13

14

আমার নির্দিষ্ট পরিস্থিতির জন্য আমি কেবলমাত্র কী এবং আদিম মান যতদূর যায় অবজেক্টের সাম্যতা সম্পর্কে যত্নশীল। আমার জন্য যে সমাধানটি কাজ করেছিল তা হ'ল বস্তুটিকে তার JSON উপস্থাপনায় রূপান্তর করা এবং হ্যাশ হিসাবে ব্যবহার করা। মূল সংজ্ঞা সম্ভাব্যভাবে বেমানান হওয়ার আদেশের মতো সীমাবদ্ধতা রয়েছে; তবে আমি যেমন বলেছিলাম এটি আমার পক্ষে কাজ করেছে কারণ এই বিষয়গুলি সমস্ত এক জায়গায় তৈরি করা হয়েছিল।

var hashtable = {};

var myObject = {a:0,b:1,c:2};

var hash = JSON.stringify(myObject);
// '{"a":0,"b":1,"c":2}'

hashtable[hash] = myObject;
// {
//   '{"a":0,"b":1,"c":2}': myObject
// }

10

আমি স্ট্রিং, অবজেক্টস, অ্যারে ইত্যাদির জন্য হ্যাশকোড তৈরি করতে কিছুক্ষণ আগে একটি ছোট জাভাস্ক্রিপ্ট মডিউল একসাথে রেখেছি (আমি এটি কেবল গিটহাবের কাছে দিয়েছিলাম :))

ব্যবহার:

Hashcode.value("stackoverflow")
// -2559914341
Hashcode.value({ 'site' : "stackoverflow" })
// -3579752159

জাভাস্ক্রিপ্টের জিসি চক্রাকার রেফারেন্সগুলিতেও শ্বাসরোধ করে না?
ক্লেটন রাবেদা

@ রায়ান লং আমি যতদূর বলতে পারা যায় যে আপনার যদি বিজ্ঞপ্তি রেফারেন্স থাকে তবে আপনার কোডটি রিফ্যাক্ট করতে হবে;)
ধাতব স্টর্ম

11
@ ধাতব স্টর্ম "তারপরে আপনার কোডটি রিফ্যাক্টর করা দরকার" আপনি কি মজা করছেন? প্রতিটি ডিওএম উপাদান পিতামাতার এবং সন্তানের জুটি একটি বিজ্ঞপ্তি রেফারেন্স গঠন করে।
ক্রিস মিডলটন

8
এটি একটি দুর্বল কাজ হ্যাশিং অবজেক্টের সংখ্যাসূচক বৈশিষ্ট্যযুক্ত রয়েছে, অনেক ক্ষেত্রে একই মান ফিরে আসে, var hash1 = Hashcode.value({ a: 1, b: 2 }); var hash2 = Hashcode.value({ a: 2, b: 1 }); console.log(hash1, hash2);লগইন করবে2867874173 2867874173
জুলিয়ান বারুব

9

জাভাস্ক্রিপ্ট স্পেসিফিকেশন সূচকের নামের উপর একটি স্ট্রিং রূপান্তর সম্পাদন হিসাবে সূচকযুক্ত সম্পত্তি অ্যাক্সেসকে সংজ্ঞায়িত করে। উদাহরণ স্বরূপ,

myObject[myProperty] = ...;

হিসাবে একই

myObject[myProperty.toString()] = ...;

এটি জাভাস্ক্রিপ্ট হিসাবে প্রয়োজনীয়

myObject["someProperty"]

হিসাবে একই

myObject.someProperty

এবং হ্যাঁ, এটি আমাকে দু: খিত করে তোলে :-(


9

ইসমাস্ক্রিপ্ট In-তে এখন এমন একটি রয়েছে Setযা আপনার পছন্দ মত কাজ করে: https://developer.mozilla.org/en-US/docs/Web/JavaScript/References/Gobbal_Objects/Set

এটি ইতিমধ্যে সর্বশেষতম ক্রোম, এফএফ এবং আই 11 এ উপলব্ধ।


1
এটি ২০১ 2016 সালের শীর্ষের উত্তর হওয়া উচিত you আপনি যদি ব্যাবেল ব্যবহার করেন তবে আপনি প্রতি ES6 স্পেক সেট ব্যবহার করতে পারেন এবং এটি ES5 আউটপুটে স্বয়ংক্রিয়ভাবে পলফিল হবে। babeljs.io/docs/learn-es2015/#map-set-weak-map-weak-set
atroberts20

5

তথ্যসূত্র: https://developer.mozilla.org/en-US/docs/Web/ জাভা স্ক্রিপ্ট / রেফারেন্স / গ্লোবাল_অবজেক্টস / সিম্বল

আপনি অনন্য কী এবং অ্যাক্সেস অবজেক্ট তৈরি করতে Es6 প্রতীক ব্যবহার করতে পারেন। প্রতীক () থেকে প্রত্যাবর্তিত প্রতিটি প্রতীক মানটি অনন্য। প্রতীক মানটি বস্তুর বৈশিষ্ট্যের জন্য সনাক্তকারী হিসাবে ব্যবহার করা যেতে পারে; এটি ডেটা টাইপের একমাত্র উদ্দেশ্য।

var obj = {};

obj[Symbol('a')] = 'a';
obj[Symbol.for('b')] = 'b';
obj['c'] = 'c';
obj.d = 'd';

2
প্রতীকটি পুনঃজন্মের সত্যিকার অর্থে উপায় নেই তবে x = চিহ্ন ('a'); যাক y = প্রতীক ('a'); কনসোল.লগ (x === y); // মিথ্যা ফিরিয়ে দেয় তাই প্রতীক হ্যাশের মতো কাজ করে না।
রিচার্ড কোলেট

3

এখানে আমার সহজ সমাধান যা একটি অনন্য পূর্ণসংখ্যা ফেরত দেয়।

function hashcode(obj) {
    var hc = 0;
    var chars = JSON.stringify(obj).replace(/\{|\"|\}|\:|,/g, '');
    var len = chars.length;
    for (var i = 0; i < len; i++) {
        // Bump 7 to larger prime number to increase uniqueness
        hc += (chars.charCodeAt(i) * 7);
    }
    return hc;
}

2
এর জটিলতা হ্যাশকোড () এর পিছনে পুরো ধারণাটিকে ক্ষুন্ন করে
tuxSlayer

আমি এটিকে জটিলভাবে খুঁজে পাই না। আমি কৌতূহল ছিল, যদিও: কেন প্রতিস্থাপন পর্ব? বাদগুলি অন্যথায় চারকোডএটে জরিমানা ফিরে আসত, তাই না?
গ্রেগ পেটিট

hashcode({a:1, b:2}) === hashcode({a:2, b:1})এবং অন্যান্য অনেক দ্বন্দ্বের কারণে খুব খারাপ ।
মার্টিনাস

3

শিরোনামের উপর ভিত্তি করে, আমরা জেএস সহ শক্তিশালী হ্যাশ তৈরি করতে পারি, এটি কোনও অবজেক্ট, প্যারামের একটি অ্যারে, একটি স্ট্রিং বা যে কোনও কিছু থেকে একটি অনন্য হ্যাশ উত্পন্ন করতে ব্যবহৃত হতে পারে।

পরবর্তীতে এটি সূচিত করার জন্য কোনও সম্ভাব্য মিলে যাওয়া ত্রুটিগুলি এড়ানোর জন্য, যখন প্যারামগুলি থেকে কোনও সূচক পুনরুদ্ধার করার অনুমতি দেয় (বস্তুর সন্ধান / লুপিং এড়ানো ইত্যাদি):

async function H(m) {
  const msgUint8 = new TextEncoder().encode(m)                       
  const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8)          
  const hashArray = Array.from(new Uint8Array(hashBuffer))                    
  const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('')
  console.log(hashHex)
}

/* Examples ----------------------- */
H("An obscure ....")
H(JSON.stringify( {"hello" : "world"} ))
H(JSON.stringify( [54,51,54,47] ))

আমার ব্রাউজারে উপরের আউটপুটটি আপনার পক্ষেও সমান হওয়া উচিত ( এটি কি সত্য? ):

bf1cf3fe6975fe382ab392ec1dd42009380614be03d489f23601c11413cfca2b
93a23971a914e5eacbf0a8d25154cda309c3c1c72fbb9914d47c60f3cb681588
d2f209e194045604a3b15bdfd7502898a0e848e4603c5a818bd01da69c00ad19

https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#Converting_a_digest_to_a_hex_string


1

আমার সমাধান গ্লোবাল Objectঅবজেক্টের জন্য একটি স্ট্যাটিক ফাংশন প্রবর্তন করে ।

(function() {
    var lastStorageId = 0;

    this.Object.hash = function(object) {
        var hash = object.__id;

        if (!hash)
             hash = object.__id = lastStorageId++;

        return '#' + hash;
    };
}());

আমি মনে করি এটি জাভাস্ক্রিপ্টে অন্যান্য অবজেক্ট কারসাজির সাথে আরও সুবিধাজনক।


1
একই অভ্যন্তরীণ মানগুলির সাথে অবজেক্টগুলি বিভিন্ন হ্যাশগুলিতে হ্যাশ করবে, এটি একটি হ্যাশ (কোড) করে না।
ধাতব ঝড়

জাভাস্ক্রিপ্টে (এবং আমি প্রায় প্রতিটি অন্যান্য ভাষায়ও মনে করি) একই অভ্যন্তরীণ মানগুলির সাথে তৈরি দুটি বস্তু এখনও পৃথক বস্তু, কারণ অন্তর্নিহিত ডেটা টাইপ প্রতিটি নতুন অবজেক্ট উদাহরণ দ্বারা উপস্থাপিত হয়। jsfiddle.net/h4G9f
জনি

4
হ্যাঁ তবে এটি হ্যাশকোডের জন্য নয়, হ্যাশকোডগুলি কোনও অবজেক্টের রাষ্ট্রের সমতা পরীক্ষা করার জন্য ব্যবহৃত হয়। ঠিক যেমন একটি হ্যাশ, একই ইনপুটগুলি যায় (পরিবর্তনশীল মান) একই হ্যাশ বের হয়। আপনি যা সন্ধান করছেন তা হ'ল একটি ইউইউডি (যা আপনার ফাংশনটি সরবরাহ করে)।
ধাতব ঝড়

1
তুমি ঠিক বলছো. আমি প্রশ্ন মিস করছি। সত্যই খারাপ, গ্রহণযোগ্য উত্তরটিও কোনও ভাল সমাধান সরবরাহ করে না।
জনি

আপনার ফাংশনটিও গ্রহণ করে, আমি এটির মতো আরও ঝুঁকির মধ্যে পড়ব : jsfiddle.net/xVSsd একই ফল, সংক্ষিপ্ত (এলওসি + অক্ষর), এবং সম্ভবত একটি ছোট্ট সামান্য দ্রুত :) :)
ধাতবতা 18

1

আমি অন্যান্য উত্তরের চেয়ে কিছুটা গভীর থেকে যাওয়ার চেষ্টা করব।

জেএসের আরও ভাল হ্যাশিং সমর্থন থাকলেও এটি যাদুকরভাবে পুরোপুরি হ্যাশ করে না, অনেক ক্ষেত্রে আপনাকে নিজের হ্যাশ ফাংশনটি সংজ্ঞায়িত করতে হবে। উদাহরণস্বরূপ জাভাতে ভাল হ্যাশিং সমর্থন রয়েছে তবে আপনাকে এখনও কিছু ভাবতে হবে এবং কাজ করতে হবে।

একটি সমস্যা হ্যাশ / হ্যাশকোড শব্দটি সহ ... এখানে ক্রিপ্টোগ্রাফিক হ্যাশিং এবং নন-ক্রিপ্টোগ্রাফিক হ্যাশিং রয়েছে। অন্যান্য সমস্যা, হ্যাশিং কেন দরকারী এবং এটি কীভাবে কাজ করে তা আপনাকে বুঝতে হবে।

যখন আমরা জাভাস্ক্রিপ্ট বা জাভাতে হ্যাশিংয়ের কথা বলি আমরা বেশিরভাগ সময় নন-ক্রিপ্টোগ্রাফিক হ্যাশিং সম্পর্কে কথা বলি, সাধারণত হ্যাশম্যাপ / হ্যাশ টেবিলের জন্য হ্যাশিং সম্পর্কে (যদি না আমরা প্রমাণীকরণ বা পাসওয়ার্ডগুলিতে কাজ করি যা আপনি নোডজেএস ব্যবহার করে সার্ভার-সাইড করছেন doing ..)।

এটি আপনার কাছে কী ডেটা রয়েছে এবং আপনি কী অর্জন করতে চান তার উপর নির্ভর করে।

আপনার ডেটাতে কিছু প্রাকৃতিক "সাধারণ" স্বতন্ত্রতা রয়েছে:

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

আপনার ডেটাতে কিছু প্রাকৃতিক "যৌগিক" স্বতন্ত্রতা রয়েছে:

  • উদাহরণস্বরূপ কোনও ব্যক্তির অবজেক্টের সাথে, আপনি প্রথম নাম, পদবি, জন্ম তারিখ, ... ব্যবহার করে একটি হ্যাশ গণনা করতে পারেন ... জাভা কীভাবে তা দেখুন: স্ট্রিংগুলির জন্য ভাল হ্যাশ ফাংশন , বা আপনার ব্যবহারের জন্য উপযুক্ত এবং অনন্য এমন কিছু আইডি তথ্য ব্যবহার করুন

আপনার ডেটা কী হবে আপনার কোনও ধারণা নেই:

  • শুভকামনা ... আপনি স্ট্রিংটিতে সিরিয়ালাইজ করতে পারেন এবং এটি জাভা স্টাইলে হ্যাশ করতে পারেন, তবে স্ট্রিং বড় হলে এটি ব্যয়বহুল হতে পারে এবং এটি সংঘর্ষ এড়াতে পারবেন না এবং পাশাপাশি একটি পূর্ণসংখ্যার (স্ব) হ্যাশও বলবে।

অজানা তথ্যের জন্য কোনও ম্যাজিকালি দক্ষ হ্যাশিং কৌশল নেই, কিছু ক্ষেত্রে এটি বেশ সহজ, অন্য ক্ষেত্রে আপনাকে দুবার ভাবতেও পারে। সুতরাং এমনকি জাভাস্ক্রিপ্ট / ইসিএমএসক্রিপ্ট আরও সমর্থন যুক্ত করলেও এই সমস্যার জন্য কোনও ম্যাজিক ভাষার সমাধান নেই।

অনুশীলনে আপনার দুটি জিনিস দরকার: যথেষ্ট স্বতন্ত্রতা, পর্যাপ্ত গতি

এটি ছাড়াও এটি দুর্দান্ত যে: "হ্যাশকোড সমান হলে বস্তু সমান হবে"


0

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

"হ্যাশকে একটি সহযোগী অ্যারে হিসাবে বিবেচনা করা যেতে পারে, মানগুলিতে অনন্য কীগুলি আবদ্ধ করা (যা প্রয়োজনীয়ভাবে অনন্য নয়) ..."

http://www.prototypejs.org/api/hash


0

চোখের পলকের উত্তর ছাড়াও, এখানে এমন একটি ফাংশন যা কোনও বস্তুর জন্য প্রজননযোগ্য, অনন্য আইডি প্রদান করে:

var uniqueIdList = [];
function getConstantUniqueIdFor(element) {
    // HACK, using a list results in O(n), but how do we hash e.g. a DOM node?
    if (uniqueIdList.indexOf(element) < 0) {
        uniqueIdList.push(element);
    }
    return uniqueIdList.indexOf(element);
}

আপনি দেখতে পাচ্ছেন এটি লুক-আপের জন্য একটি তালিকা ব্যবহার করে যা খুব অদক্ষ, তবে এটি এখনকার জন্য আমি খুঁজে পেতে পারি এটি সেরা।


0

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

আমি একটি ছোট গ্রন্থাগার লিখেছি যা বস্তুগুলি থেকে হ্যাশ তৈরি করে, যা আপনি সহজেই এই উদ্দেশ্যে ব্যবহার করতে পারেন। বস্তুগুলির এমনকি একটি পৃথক ক্রম থাকতে পারে, হ্যাশগুলি একই হবে। অভ্যন্তরীণভাবে আপনি আপনার হ্যাশের জন্য বিভিন্ন ধরণের ব্যবহার করতে পারেন (ডিজেবি 2, এমডি 5, শ 1, শ 256, শা512, রিপেমড160)।

ডকুমেন্টেশন থেকে এখানে একটি ছোট উদাহরণ রয়েছে:

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

// Save data in an object with an object as a key
Object.prototype.toString = function () {
    return '[object Object #'+hash(this)+']';
}

var foo = {};

foo[{bar: 'foo'}] = 'foo';

/*
 * Output:
 *  foo
 *  undefined
 */
console.log(foo[{bar: 'foo'}]);
console.log(foo[{}]);

প্যাকেজটি ব্রাউজারে এবং নোড-জেসে ব্যবহার করা যেতে পারে।

সংগ্রহস্থল: https://bitbucket.org/tehrengruber/es-js-hash


0

যদি আপনি কোনও অনুসন্ধান সামগ্রীতে অনন্য মান রাখতে চান তবে আপনি এরকম কিছু করতে পারেন:

একটি লুকিং অবজেক্ট তৈরি করা হচ্ছে

var lookup = {};

হ্যাশকোড ফাংশন সেট আপ করা হচ্ছে

function getHashCode(obj) {
    var hashCode = '';
    if (typeof obj !== 'object')
        return hashCode + obj;
    for (var prop in obj) // No hasOwnProperty needed
        hashCode += prop + getHashCode(obj[prop]); // Add key + value to the result string
    return hashCode;
}

উদ্দেশ্য

var key = getHashCode({ 1: 3, 3: 7 });
// key = '1337'
lookup[key] = true;

বিন্যাস

var key = getHashCode([1, 3, 3, 7]);
// key = '01132337'
lookup[key] = true;

অন্য ধরণের

var key = getHashCode('StackOverflow');
// key = 'StackOverflow'
lookup[key] = true;

সর্বশেষ ফলাফল

{ 1337: true, 01132337: true, StackOverflow: true }

মনে রাখবেন যে getHashCodeযখন বস্তু বা অ্যারেটি খালি থাকে তখন কোনও মান ফেরত দেয় না

getHashCode([{},{},{}]);
// '012'
getHashCode([[],[],[]]);
// '012'

এটি @ আইজ্যাক সিডি সমাধানের মতোই কেবল নির্ভরতা getHashCodeরাখে না JSON


আপনার সাথে এর সাথে বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সে সমস্যা আছে
tuxSlayer

@ টাকস্লেয়ার আমাকে জানাতে ধন্যবাদ। আপনি আপনার প্রয়োজনের সাথে এই কোডটি সহজেই প্রসারিত করতে পারেন তবে আমি আশা করি ধারণাটি কিছুটা পরিষ্কার হয়ে গেছে :)
আরপুন

এটি বড় আকারের অবজেক্টগুলির জন্য খুব দীর্ঘ কী তৈরি করবে যা স্মৃতি এবং পারফরম্যান্সকে বেশ হার্ড করতে পারে
Gershom

0

আমি চোখের পাতা এবং কিমখা থেকে উত্তরগুলি একত্রিত করেছি।

নিম্নলিখিতটি একটি কৌণিক সেবার পরিষেবা এবং এটি সংখ্যা, স্ট্রিং এবং অবজেক্টগুলিকে সমর্থন করে।

exports.Hash = () => {
  let hashFunc;
  function stringHash(string, noType) {
    let hashString = string;
    if (!noType) {
      hashString = `string${string}`;
    }
    var hash = 0;
    for (var i = 0; i < hashString.length; i++) {
        var character = hashString.charCodeAt(i);
        hash = ((hash<<5)-hash)+character;
        hash = hash & hash; // Convert to 32bit integer
    }
    return hash;
  }

  function objectHash(obj, exclude) {
    if (exclude.indexOf(obj) > -1) {
      return undefined;
    }
    let hash = '';
    const keys = Object.keys(obj).sort();
    for (let index = 0; index < keys.length; index += 1) {
      const key = keys[index];
      const keyHash = hashFunc(key);
      const attrHash = hashFunc(obj[key], exclude);
      exclude.push(obj[key]);
      hash += stringHash(`object${keyHash}${attrHash}`, true);
    }
    return stringHash(hash, true);
  }

  function Hash(unkType, exclude) {
    let ex = exclude;
    if (ex === undefined) {
      ex = [];
    }
    if (!isNaN(unkType) && typeof unkType !== 'string') {
      return unkType;
    }
    switch (typeof unkType) {
      case 'object':
        return objectHash(unkType, ex);
      default:
        return stringHash(String(unkType));
    }
  }

  hashFunc = Hash;

  return Hash;
};

ব্যবহারের উদাহরণ:

Hash('hello world'), Hash('hello world') == Hash('hello world')
Hash({hello: 'hello world'}), Hash({hello: 'hello world'}) == Hash({hello: 'hello world'})
Hash({hello: 'hello world', goodbye: 'adios amigos'}), Hash({hello: 'hello world', goodbye: 'adios amigos'}) == Hash({goodbye: 'adios amigos', hello: 'hello world'})
Hash(['hello world']), Hash(['hello world']) == Hash(['hello world'])
Hash(1), Hash(1) == Hash(1)
Hash('1'), Hash('1') == Hash('1')

আউটপুট

432700947 true
-411117486 true
1725787021 true
-1585332251 true
1 true
-1881759168 true

ব্যাখ্যা

আপনি দেখতে পাচ্ছেন যে পরিষেবাটির হৃদয় কিমখা দ্বারা নির্মিত হ্যাশ ফাংশন I আমি স্ট্রিংগুলিতে আরও কিছু প্রকার যুক্ত করেছি যাতে বস্তুর স্ট্রুচার চূড়ান্ত হ্যাশ মানকেও প্রভাবিত করে keys কীগুলি অ্যারে | অবজেক্টের সংঘর্ষ রোধ করতে হ্যাশ করা হয়।

আইলয়েডলেসনেস অবজেক্টের তুলনা স্ব-রেফারেন্সিং অবজেক্টস দ্বারা অনন্য পুনরাবৃত্তি রোধ করতে ব্যবহৃত হয়।

ব্যবহার

আমি এই পরিষেবাটি তৈরি করেছি যাতে আমার কাছে কোনও ত্রুটি পরিষেবা থাকতে পারে যা অবজেক্টের সাহায্যে অ্যাক্সেস করা যায়। যাতে একটি পরিষেবা কোনও প্রদত্ত বস্তুর সাথে ত্রুটি নিবন্ধভুক্ত করতে পারে এবং অন্যটি কোনও ত্রুটি খুঁজে পেয়েছিল কিনা তা নির্ধারণ করতে পারে।

অর্থাত

JsonValidation.js

ErrorSvc({id: 1, json: '{attr: "not-valid"}'}, 'Invalid Json Syntax - key not double quoted');

UserOfData.js

ErrorSvc({id: 1, json: '{attr: "not-valid"}'});

এটি ফিরে আসবে:

['Invalid Json Syntax - key not double quoted']

যদিও

ErrorSvc({id: 1, json: '{"attr": "not-valid"}'});

এই ফিরে আসবে

[]

0

এর সাথে গোপনীয় গোপন সম্পত্তিটি ব্যবহার করুন defineProperty enumerable: false

এটি খুব দ্রুত কাজ করে :

  • প্রথম পঠিত ইউনিকআইডি: 1,257,500 অপস / এস
  • অন্যান্য সমস্ত: 309,226,485 অপস / এস
var nextObjectId = 1
function getNextObjectId() {
    return nextObjectId++
}

var UNIQUE_ID_PROPERTY_NAME = '458d576952bc489ab45e98ac7f296fd9'
function getObjectUniqueId(object) {
    if (object == null) {
        return null
    }

    var id = object[UNIQUE_ID_PROPERTY_NAME]

    if (id != null) {
        return id
    }

    if (Object.isFrozen(object)) {
        return null
    }

    var uniqueId = getNextObjectId()
    Object.defineProperty(object, UNIQUE_ID_PROPERTY_NAME, {
        enumerable: false,
        configurable: false,
        writable: false,
        value: uniqueId,
    })

    return uniqueId
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.