কোন পূর্ণসংখ্যার হ্যাশ ফাংশনটি ভাল যা কোনও পূর্ণসংখ্যার হ্যাশ কী গ্রহণ করে?


উত্তর:


48

নুথের গুণক পদ্ধতি:

hash(i)=i*2654435761 mod 2^32

সাধারণভাবে, আপনার এমন একটি গুণক বেছে নেওয়া উচিত যা আপনার হ্যাশের আকারের ( 2^32যেমন উদাহরণের) ক্রমযুক্ত এবং এতে কোনও সাধারণ কারণ নেই। এইভাবে হ্যাশ ফাংশনটি আপনার সমস্ত হ্যাশ স্থানটি সমানভাবে কভার করে।

সম্পাদনা করুন: এই হ্যাশ ফাংশনের বৃহত্তম অসুবিধা হ'ল এটি বিভাজ্যতা সংরক্ষণ করে, সুতরাং আপনার পূর্ণসংখ্যাগুলি যদি 2 বা 4 দ্বারা বিভাজ্য হয় (যা অস্বাভাবিক নয়) তবে তাদের হ্যাশগুলিও হবে। এটি হ্যাশ টেবিলগুলির একটি সমস্যা - আপনি কেবল বালতি ব্যবহারের 1/1 বা 1/4 টি দিয়ে শেষ করতে পারেন।


38
এটি একটি বিখ্যাত নামের সাথে সংযুক্ত হলেও এটি একটি সত্যই খারাপ হ্যাশ ফাংশন।
Seun Osewa

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


8
পাওলো: নূথের পদ্ধতিটি "খারাপ" এই অর্থে যে এটি উপরের বিটগুলিতে
ঝরঝরে

10
কাছাকাছি পরিদর্শন করার পরে, এটি দেখা গেছে যে 2654435761 আসলে একটি প্রধান সংখ্যা। সুতরাং যে সম্ভবত কেন এটা চেয়ে 2654435769. বরং মনোনীত হয়েছিল
karadoc

151

আমি নিম্নলিখিত আলগোরিদিম একটি খুব ভাল পরিসংখ্যান বিতরণ সরবরাহ করে। প্রতিটি ইনপুট বিট প্রায় 50% সম্ভাব্যতা সহ প্রতিটি আউটপুট বিটকে প্রভাবিত করে। কোনও সংঘর্ষ নেই (প্রতিটি ইনপুট ফলাফল ভিন্ন আউটপুট)। সিপিইউতে অন্তর্নির্মিত পূর্ণসংখ্যা গুণক একক না থাকলে ব্যতীত অ্যালগরিদম দ্রুত। সি কোড, অভিমানী int32 বিট (জাভা জন্য, প্রতিস্থাপন হয় >>সঙ্গে >>>এবং অপসারণ unsigned):

unsigned int hash(unsigned int x) {
    x = ((x >> 16) ^ x) * 0x45d9f3b;
    x = ((x >> 16) ^ x) * 0x45d9f3b;
    x = (x >> 16) ^ x;
    return x;
}

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

আপনি প্রক্রিয়াটি বিপরীত করতে পারেন (হ্যাশ থেকে ইনপুট মান পাবেন) যদি আপনি এর 0x45d9f3bসাথে 0x119de1f3( গুণিত বিপরীত ) প্রতিস্থাপন করেন :

unsigned int unhash(unsigned int x) {
    x = ((x >> 16) ^ x) * 0x119de1f3;
    x = ((x >> 16) ^ x) * 0x119de1f3;
    x = (x >> 16) ^ x;
    return x;
}

-৪-বিট সংখ্যার জন্য, আমি নিম্নলিখিতটি ব্যবহার করার পরামর্শ দিই, এমনকি ভেবেছিলাম এটি সম্ভবত দ্রুত নয়। এইটি স্প্লিটমিক্স 64৪ এর উপর ভিত্তি করে তৈরি হয়েছে যা মনে হয় ব্লগার আর্টিকেল বেটার বিট মিক্সিংয়ের (মিক্স ১৩) উপর ভিত্তি করে ।

uint64_t hash(uint64_t x) {
    x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
    x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
    x = x ^ (x >> 31);
    return x;
}

জাভা, ব্যবহারের জন্য longযোগ, Lধ্রুবক হয়, প্রতিস্থাপন >>সঙ্গে >>>এবং অপসারণ unsigned। এই ক্ষেত্রে, বিপরীতকরণ আরও জটিল:

uint64_t unhash(uint64_t x) {
    x = (x ^ (x >> 31) ^ (x >> 62)) * UINT64_C(0x319642b2d24d8ec3);
    x = (x ^ (x >> 27) ^ (x >> 54)) * UINT64_C(0x96de1b173f119089);
    x = x ^ (x >> 30) ^ (x >> 60);
    return x;
}

আপডেট: আপনি হ্যাশ ফাংশন প্রসপেক্টর প্রকল্পটিও দেখতে চাইতে পারেন , যেখানে অন্যান্য (সম্ভবত আরও ভাল) স্থির তালিকাভুক্ত রয়েছে।


4
প্রথম দুটি লাইন ঠিক একই! এখানে কি টাইপো আছে?
ক্ষিতিজ ব্যানার্জি

4
না এটি কোনও টাইপো নয়, দ্বিতীয় লাইনটি আরও বিটগুলিতে মিশে। মাত্র একটি গুণ ব্যবহার করা ততটা ভাল নয়।
টমাস মুলার

4
আমি ম্যাজিক নম্বরটি পরিবর্তন করেছি কারণ একটি পরীক্ষার কেস অনুসারে আমি লিখেছি মান 0x45d9f3b আরও ভাল বিভ্রান্তি এবং প্রসারণ সরবরাহ করে , বিশেষত যে যদি একটি আউটপুট বিট পরিবর্তন হয় তবে একে অপরের আউটপুট বিট একই সম্ভাবনার সাথে পরিবর্তন হয় (সমস্ত আউটপুট বিট ছাড়াও এর সাথে পরিবর্তন হয়) যদি কোনও ইনপুট বিট পরিবর্তন হয় তবে একই সম্ভাবনা। আপনি কীভাবে 0x3335b369 পরিমাপ করেছেন আপনার জন্য আরও ভাল কাজ করে? আপনার জন্য কোন 32 বিট?
টমাস মুলার

4
আমি 32 বিট স্বাক্ষরবিহীন ইন্ট থেকে 64 বিট স্বাক্ষরযুক্ত ইন্টের জন্য একটি দুর্দান্ত হ্যাশ ফাংশনটি অনুসন্ধান করছি। এই ক্ষেত্রে, উপরে যাদু নম্বর একই হবে? আমি 16 বিটের পরিবর্তে 32 বিট স্থানান্তরিত করেছি।
আলেসান্দ্রো

4
আমি বিশ্বাস করি সে ক্ষেত্রে আরও বড় ফ্যাক্টর আরও ভাল হবে তবে আপনাকে কিছু পরীক্ষা চালানো দরকার। অথবা (এটি আমি যা করি) প্রথমে ব্যবহার করুন x = ((x >> 32) ^ x)এবং তারপরে উপরের 32 বিট গুণগুলি ব্যবহার করুন। আমি নিশ্চিত না আরও ভাল কি। আপনি মারমুর 3
টমাস

29

আপনার ডেটা কীভাবে বিতরণ করা হবে তার উপর নির্ভর করে। একটি সাধারণ কাউন্টার জন্য, সহজতম ফাংশন

f(i) = i

ভাল হবে (আমি অনুকূল সন্দেহ করি, তবে আমি এটি প্রমাণ করতে পারি না)।


4
এটির সাথে সমস্যাটি হ'ল প্রচলিত সংখ্যার পূর্ণসংখ্যক সংখ্যা যা সাধারণ ফ্যাক্টর দ্বারা বিভাজ্য হয় (শব্দ-সংযুক্ত মেমরি অ্যাড্রেস ইত্যাদি) etc. এখন যদি আপনার হ্যাশ টেবিলটি একই ফ্যাক্টর দ্বারা বিভাজনযোগ্য হয়, আপনি কেবল অর্ধেক (বা 1/4, 1/8 ইত্যাদি) বালতি ব্যবহার করে শেষ করেন।
রাফা ডগির্ড

8
@ রাফাল: এ কারণেই প্রতিক্রিয়াটি "একটি সাধারণ কাউন্টারের জন্য" এবং "আপনার ডেটা কীভাবে বিতরণ করা হয় তার উপর নির্ভর করে" বলে জানিয়েছে
এরিক্কল্লান

5
এটা আসলে java.lang.Integer পদ্ধতি হ্যাশকোড সূর্য () দ্বারা বাস্তবায়ন এর grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/...
Juande ক্যারিওন

5
পছন্দ করুন দুটি টেবিল মাপের পাওয়ার ব্যবহার করতে যাওয়ার পরে, জাভা প্রতিটি হ্যাশ থেকে ফিরে আসা পুনঃস্থাপন করে .hashCode(), দেখুন এখানে
ইসাইলিজা

8
বিতরণযোগ্য বৈশিষ্ট্যগুলির (বা এর অভাবের কারণে) ব্যবহারিক প্রয়োগগুলিতে পরিচয় ফাংশনটি হ্যাশ হিসাবে মোটামুটি অকেজো, যদি না অবশ্যই, স্থানীয়তা কোনও পছন্দসই গুণ নয়
awdz9nld

12

দ্রুত এবং ভাল হ্যাশ ফাংশনগুলিকে কম গুণাবলীর মতো দ্রুত নির্গমন থেকে রচনা করা যেতে পারে

  • অসম পূর্ণসংখ্যার সাথে গুণ
  • বাইনারি ঘূর্ণন
  • xorshift

র্যান্ডম সংখ্যা জেনারেশনের জন্য পিসিজি দিয়ে প্রদর্শিত যেমন উন্নত গুণাবলীর সাথে একটি হ্যাশিং ফাংশন উপস্থাপন করা ।

এটি আসলে rrxmrrxxx_0 এবং মুরমার হ্যাশটি জেনে বা অজান্তে ব্যবহার করছে recipe

আমি ব্যক্তিগতভাবে খুঁজে পেয়েছি

uint64_t xorshift(const uint64_t& n,int i){
  return n^(n>>i);
}
uint64_t hash(const uint64_t& n){
  uint64_t p = 0x5555555555555555ull; // pattern of alternating 0 and 1
  uint64_t c = 17316035218449499591ull;// random uneven integer constant; 
  return c*xorshift(p*xorshift(n,32),32);
}

যথেষ্ট ভাল হতে।

একটি ভাল হ্যাশ ফাংশন করা উচিত

  1. যদি সম্ভব হয় তবে তথ্যটি আলগা না করে বাইজেক্টেভ হন এবং কমপক্ষে সংঘর্ষ হয়
  2. যতটা সম্ভব ক্যাসকেড এবং যতটা সম্ভব সমান, অর্থাৎ প্রতিটি ইনপুট বিটের সম্ভাব্যতা 0.5 এর সাথে প্রতিটি আউটপুট বিট ফ্লিপ করা উচিত।

আসুন প্রথমে পরিচয় ফাংশনটি দেখুন। এটি সন্তুষ্ট 1. তবে নয় 2:

পরিচয় ফাংশন

ইনপুট বিট এন 100% (লাল) এবং অন্য কারও সাথে সম্পর্কিত না করে আউটপুট বিট এন নির্ধারণ করে, এগুলি তাই নীল, একেবারে নিখুঁত লাল রেখা সরবরাহ করে।

একটি xorshift (এন, 32) খুব ভাল হয় না, দেড় লাইনের ফলন দেয়। তবু সন্তুষ্ট 1., কারণ এটি দ্বিতীয় প্রয়োগের সাথে অবিচ্ছিন্ন।

xorshift

স্বাক্ষরবিহীন পূর্ণসংখ্যার সাথে একটি গুণটি আরও ভাল, আরও দৃ strongly়ভাবে ক্যাসকেড করা এবং 0.5 এর সম্ভাব্যতার সাথে আরও আউটপুট বিটগুলি উল্টানো, যা আপনি চান, সবুজ in এটি 1 টি সন্তুষ্ট করে প্রতিটি অসম পূর্ণসংখ্যার জন্য একটি গুণক বিপরীত থাকে।

গিঁট

দুটি সংমিশ্রণ নিম্নলিখিত আউটপুট দেয়, এখনও সন্তুষ্ট 1। দুটি দ্বি দ্বিপ্রদীপক ফাংশন গঠনের ফলে আরও একটি দ্বিঘাতমূলক ফাংশন পাওয়া যায়।

নথ • xorshift

গুন এবং xorshift দ্বিতীয় প্রয়োগ নিম্নলিখিত উত্পাদন করবে:

প্রস্তাবিত হ্যাশ

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

   uint64_t const inline gfmul(const uint64_t& i,const uint64_t& j){           
     __m128i I{};I[0]^=i;                                                          
     __m128i J{};J[0]^=j;                                                          
     __m128i M{};M[0]^=0xb000000000000000ull;                                      
     __m128i X = _mm_clmulepi64_si128(I,J,0);                                      
     __m128i A = _mm_clmulepi64_si128(X,M,0);                                      
     __m128i B = _mm_clmulepi64_si128(A,M,0);                                      
     return A[0]^A[1]^B[1]^X[0]^X[1];                                              
   }

জিএফএমুল: কোডটি সিউডো কোড হিসাবে উপস্থিত বলে মনে হচ্ছে, আফাইক আপনি __m128i সহ বন্ধনী ব্যবহার করতে পারবেন না। এখনও খুব আকর্ষণীয়। প্রথম লাইনে "একটি ইউনিটিয়ালাইজড __m128i (I) নিন এবং এটিকে (পরামিতি) দিয়ে xor করা হবে বলে মনে হচ্ছে i। আমি কি এটি 0 এবং I দিয়ে xor দিয়ে ইনিশিয়াল হিসাবে পড়তে পারি? যদি তাই হয় তবে এটি কি আমার সাথে লোডের সমান হবে? এবং আমি একটি (অপারেশন) সঞ্চালন?
জানুয়ারী

@ জান আমি যা করতে চাই তা হ'ল __m128i I = i; //set the lower 64 bitsতবে আমি তা করতে পারি না, তাই আমি ব্যবহার করছি ^=0^1 = 1সুতরাং কোন চালিত হয় নি। {}আমার সংকলকটির সাথে আরম্ভের বিষয়ে কখনও অভিযোগ করেনি, এটি সেরা সমাধান নাও হতে পারে তবে আমি এটির সাথে যা চাই তা সবগুলি 0 তে শুরু করা যাতে আমি করতে পারি ^=বা করতে পারি |=। আমি ভিত্তিক কোডটি মনে এই ব্লগপোস্টটিকে ডি: যা বিপর্যয়, খুব দরকারী দেয়
উলফগ্যাং Brehm


6

এই পৃষ্ঠায় কিছু সাধারণ হ্যাশ ফাংশন তালিকাভুক্ত করা হয় যা সাধারণভাবে শালীনভাবে প্রবণতা রাখে, তবে যে কোনও সাধারণ হ্যাশটিতে প্যাথোলজিকাল কেস রয়েছে যেখানে এটি কার্যকর হয় না।


3

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


4
এটি একটি ভাল নিবন্ধ, তবে এটি পূর্ণসংখ্যার চেয়ে নয় স্ট্রিং কীগুলিতে হ্যাশিংয়ের উপর केंद्रित।
অ্যাড্রিয়ান মৌআত

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

2

উত্তর অনেক কিছুর উপর নির্ভর করে:

  • আপনি এটি নিয়োগ করার ইচ্ছা কোথায়?
  • আপনি হ্যাশ দিয়ে কি করতে চেষ্টা করছেন?
  • আপনার কি ক্রিটোগ্রাফিকভাবে সুরক্ষিত হ্যাশ ফাংশন দরকার?

আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি SHA-1 ইত্যাদির মতো হ্যাশ ফাংশনগুলির Merkle-Damgard পরিবারের দিকে একবার নজর দিন


1

আমি মনে করি না যে আমরা বলতে পারি যে কোনও হ্যাশ ফাংশনটি আগে থেকে আপনার ডেটা না জেনে "ভাল"! এবং আপনি এটি দিয়ে কি করতে যাচ্ছেন তা না জেনে।

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


1

এলোমেলো হ্যাশ মানগুলির জন্য, কয়েকজন প্রকৌশলী বলেছিলেন যে সোনালি অনুপাতের প্রাইম সংখ্যা (2654435761) একটি খারাপ পছন্দ, আমার পরীক্ষার ফলাফলের সাথে আমি খুঁজে পেয়েছি যে এটি সত্য নয়; পরিবর্তে, 2654435761 হ্যাশ মানগুলি বেশ ভাল বিতরণ করে।

#define MCR_HashTableSize 2^10

unsigned int
Hash_UInt_GRPrimeNumber(unsigned int key)
{
  key = key*2654435761 & (MCR_HashTableSize - 1)
  return key;
}

হ্যাশ টেবিলের আকারটি অবশ্যই দুটি শক্তির হতে হবে।

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

আমি চেষ্টা করেছি:

  1. মোট_ডাটা_সেন্ট্রি_ সংখ্যা / মোট_বাকেট_নিম্বার = 2, 3, 4; যেখানে মোট_বকেট_নম্বার = হ্যাশ টেবিলের আকার;
  2. বালতি সূচক ডোমেনে মানচিত্রের হ্যাশ মান ডোমেন; এটি হ্যাশ_উইন্ট_জিআরপ্রাইমনিম্বার () -তে প্রদর্শিত হ্যাশ মানটিকে লজিকাল অ্যান্ড অপারেশন দ্বারা বালিশ সূচকে রূপান্তর করুন (hash_table_size - 1);
  3. প্রতিটি বালতির সংঘর্ষের সংখ্যা গণনা করুন;
  4. ম্যাপ করা হয়নি এমন বালতিটি রেকর্ড করুন, এটি একটি খালি বালতি;
  5. সমস্ত বালতির সর্বাধিক সংঘর্ষের সংখ্যাটি সন্ধান করুন; যে, দীর্ঘতম চেইন দৈর্ঘ্য;

আমার পরীক্ষার ফলাফলের সাথে, আমি দেখতে পেলাম যে গোল্ডেন রেশিয়ো প্রাইম নাম্বারে সর্বদা কম খালি বালতি বা শূন্য শূন্য বালতি এবং সংক্ষিপ্ত সংঘর্ষ শৃঙ্খলার দৈর্ঘ্য রয়েছে।

পূর্ণসংখ্যার জন্য কিছু হ্যাশ ফাংশন ভাল বলে দাবি করা হয়, তবে পরীক্ষার ফলাফলগুলি দেখায় যে মোট_ডেটা_সেন্টারি / মোট_বকেট_নিম্বার = 3 যখন দীর্ঘতম চেইনের দৈর্ঘ্য 10 (সর্বোচ্চ সংঘর্ষের সংখ্যা> 10) এর চেয়ে বড় হয় এবং অনেকগুলি বালতি ম্যাপ করা হয় না (খালি বালতি) ) গোল্ডেন রেশিও প্রাইম নম্বর হ্যাশিংয়ের শূন্য শূন্য বালতি এবং দীর্ঘতম চেইন দৈর্ঘ্যের 3 এর ফলাফলের সাথে তুলনা করে এটি খুব খারাপ।

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

unsigned int Hash_UInt_M3(unsigned int key)
{
  key ^= (key << 13);
  key ^= (key >> 17);    
  key ^= (key << 5); 
  return key;
}

4
তবে কেন সঠিকভাবে পণ্যটি স্থানান্তরিত করবেন না, তাই আপনি সর্বাধিক মিশ্রিত বিটগুলি রাখেন? এটিই কাজ করার কথা ছিল
হ্যালোলে

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

(2654435761, 4295203489) প্রাইমের স্বর্ণের অনুপাত।
চেন-চুংচিয়া

(1640565991, 2654435761) প্রাইমগুলির স্বর্ণের অনুপাতও।
চেন-চুংচিয়া

@ হোল্ড, পণ্যটি ডান স্থানান্তর করা আরও খারাপ হয়ে যায়, এমনকি যদি কেবল 1 পজিশনে ডান স্থানান্তর করে (2 দ্বারা বিভাজিত হয়), এটি এখনও আরও খারাপ হয় (যদিও শূন্য বালতি শূন্য হলেও দীর্ঘতম চেইনের দৈর্ঘ্য বড়); আরও অবস্থানের দ্বারা ডান স্থানান্তর, ফলাফল আরও খারাপ হয়। কেন? আমি মনে করি কারণটি হ'ল: পণ্যটি ডান স্থানান্তর করা আরও হ্যাশ মানকে কপিরাইম না করে তোলে, কেবল আমার অনুমান, আসল কারণটিতে সংখ্যার তত্ত্ব জড়িত।
চেন-চুংচিয়া

1

আমি যখন থেকে এই থ্রেডটি পেয়েছি তখন থেকেই আমি splitmix64(থমাস মুলারের উত্তরে নির্দেশিত ) ব্যবহার করছি। যাইহোক, আমি সম্প্রতি পেলে ইভেনসেনের rrxmrrxmsx_0 কে হোঁচট খেয়েছি , যা মূল মার্মুরহ্যাশ 3 ফাইনালাইজার এবং এর উত্তরসূরিদের ( splitmix64এবং অন্যান্য মিশ্রণ) এর চেয়ে মারাত্মকভাবে পরিসংখ্যান বিতরণ পেয়েছিল । সি তে কোড স্নিপেট এখানে রয়েছে:

#include <stdint.h>

static inline uint64_t ror64(uint64_t v, int r) {
    return (v >> r) | (v << (64 - r));
}

uint64_t rrxmrrxmsx_0(uint64_t v) {
    v ^= ror64(v, 25) ^ ror64(v, 50);
    v *= 0xA24BAED4963EE407UL;
    v ^= ror64(v, 24) ^ ror64(v, 49);
    v *= 0x9FB21C651E98DF25UL;
    return v ^ v >> 28;
}

পেলে চূড়ান্ত ধাপে ব্যবহৃত 64-বিট মিক্সারের আরও গভীরতর বিশ্লেষণMurmurHash3 এবং আরও সাম্প্রতিকতম রূপগুলি সরবরাহ করে।


4
এই ফাংশন বাইজিক নয়। সমস্ত v এর জন্য যেখানে v = ror (v, 25), সমস্ত 0 এবং সমস্ত 1 এটি দুটি জায়গায় একই আউটপুট উত্পাদন করবে। সমস্ত মানগুলির জন্য v = ror64 (v, 24) or ror64 (v, 49), যা কমপক্ষে আরও দুটি এবং v = ror (v, 28) এর সাথে একই, আরও 2 ^ 4 পাওয়া যায়, প্রায় 22 টি অপ্রয়োজনীয় সংঘর্ষের প্রায় । স্প্লিটমিক্সের দুটি অ্যাপ্লিকেশন সম্ভবত ঠিক তত ভাল এবং তত দ্রুত, তবে এখনও অবিচ্ছিন্ন এবং সংঘর্ষ-মুক্ত।
ওল্ফগ্যাং ব্রেহম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.