PDA

View Full Version : String.HashCode



HAIdle
شنبه 27 مرداد 1386, 18:21 عصر
با سلام
کلاس String تابعی به نام GetHashCode دارد. کسی می دونه HashCode یک رشته چیه؟

omid_Ahmadi
شنبه 27 مرداد 1386, 18:32 عصر
این تابع مربوط به کلاس Object هست، بنابراین می تونی توی همه کلاسهایی که در .NET وجود دارن این تابع رو ببینی. وطیفه این تابع هم اینه که یه Hash Code برمی گردونه. اگر در مورد Hash Code نمی دونی، بگو.

موفق باشی

hdv212
شنبه 27 مرداد 1386, 18:44 عصر
همانطور که omid_Ahmadi عزیز گفت، GetHashCode عضو کلاس آبجکت هست، پس در تمام کلاسهای .net قابل دستیابی هست. GetHashCode طبق الگوریتم پیچیده ای که در درون خودش داره، روی آبجکت شما محاسباتی رو انجام میده و نتیجه رو به صورت یه عدد صحیح یا int بر میگردونه و مثلا شما میتونی با این مقدار به دست اومده کنترل کنی که آیا آبجکت مورد نظر، همون آبجکتی هست که HashCode اون رو به دست آوردی یا نه، لازم به ذکر هست که متد GetHashCode بازگشتی نیست، یعنی شما نمیتونی از عدد int به دست آمده، به آبجکت مورد نظر برسی.

mehdi.mousavi
یک شنبه 28 مرداد 1386, 01:21 صبح
با سلام
کلاس String تابعی به نام GetHashCode دارد. کسی می دونه HashCode یک رشته چیه؟

سلام.
کلاس Object در DotNet Framework حاوی Virtual Method ای بنام GetHashCode هستش، که دیگر کلاسها میتونن اونو Override کنن تا پیاده سازی دلخواه خودشون رو برای این متود انجام بدن. محل مناسب استفاده از این تابع الگوریتمهای Hashing مثل Hash Table هست. مقدار پیش فرض پیاده سازی اصلی این تابع هرگز مقدار Unique ای نیست و هیچوقت هم نبوده. اگر چه یه Implementation ایده آل از این تابع چنین چیزی رو ضمانت می کنه، اما پیاده سازی چنین چیزی غیر ممکن یا غیر عملی است. اگر می خواهید این تابع رو override کنید، باید سه معیار زیر رو همیشه مد نظر داشته باشید:

اگر دو شی از یک تایپ مقدار یکسانی داشته باشن، تابع Hash باید مقدار ثابت یکسانی را بازای هر دو شی برگردونه.
برای بهترین کارایی، تابع Hash باید توزیع تصادفی بازای کلیه ورودیها تولید کنه.
جدا از کلیه تغییراتی که روی شی ممکنه اعمال بشه، تابع Hash باید دقیقا همان مقدار را برگردونه.متاسفانه بسیاری از افراد بر این باورند که تعریف اصلی String.GetHashCode بازای ورودیهای متفاوت، اعداد منحصر بفردی برمی گردونه. اما مثال نقض Mashiharu، نشان می دهد که دو ورودی متفاوت زیر کد Hash یکسانی تولید می کنند (البته در .NET FX نسخه 2):



Trace.WriteLine("0:93121".GetHashCode());

Trace.WriteLine("0:2546870".GetHashCode());
در هر حال، با توجه به توضیحات داده شده، تابع Hash را می توان با XOR کردن member value های آن کلاس (یا structure) پیاده سازی نمود:



public struct MyStruct1
{
public int field1;
public int field2;

public override int GetHashCode()
{
return field1 ^ field2;
}
}

روش متعارف دیگه، استفاده از یک عدد اول (مثل 19) هستش:



public struct MyStruct2
{
public int field1;
public int field2;
public override int GetHashCode()
{
return 19 * field1.GetHashCode() + 1 * field2.GetHashCode();
}
}
روشهای پیچیده دیگری برای پیاده سازی این تابع وجود دارد که هر یک مستلزم پست جداگانه ای است. اما روش شما هر چه که هست، از سه اصل فوق پیروی کنید. برای اطلاعات بیشتر در این زمینه لطفا این مقاله رو مطالعه کنید. (http://www.mehdi.biz/blog/2007/06/gethashcode-vs-uniqueness.html) (منبع) (http://www.mehdi.biz/blog/)

PC2st
یک شنبه 28 مرداد 1386, 10:37 صبح
مثال نقض Mashiharu، مثال خیلی جالبی بود...
موندم چطور این مثال نقض رو تونسته پیدا کنه؟! با یک حلقه for (!)؟