PDA

View Full Version : پیاده سازی تابع GetHashCode برای سایر زبان ها



#target
یک شنبه 19 آذر 1391, 22:43 عصر
سلام خدمت کاربران بخش #C
بنده برنامه نویس C هستم و به دلایلی نیاز دارم تابع String.GetHashCode که در دات نت هست رو اونجا پیاده سازی کنم
سرچ کردم ی کد پیدا کرده ولی نتیجه یا چیزی که دات نت میده تفاوت داره !
الگوریتم این تابع رو میخواستم

تابعی که من گیر آوردم {
fixed (char* str = this)
{
char* chPtr = str;
int num = 352654597;
int num2 = num;
int* numPtr = (int*)chPtr;
for (int i = this.Length; i > 0; i -= 4)
{
num = (((num << 5) + num) + (num >> 27)) ^ numPtr[0];
if (i <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 27)) ^ numPtr[1];
numPtr += 2;
}
return (num + (num2 * 1566083941));
}
}

plus
دوشنبه 20 آذر 1391, 01:35 صبح
تابع GetHashCode برای کلاس String در دات نت 3.5 به صورت زیر پیاده سازه شده:

// String.cs
// Gets a hash code for this string. If strings A and B are such that A.Equals(B), then
// they will return the same hash code.
[ReliabilityContract(Consistency.WillNotCorruptStat e, Cer.MayFail)]
public override int GetHashCode() {
unsafe {
fixed (char *src = this) {
BCLDebug.Assert(src[this.Length] == '\0', "src[this.Length] == '\\0'");
BCLDebug.Assert( ((int)src)%4 == 0, "Managed string should start at 4 bytes boundary");

#if WIN32
int hash1 = (5381<<16) + 5381;
#else
int hash1 = 5381;
#endif
int hash2 = hash1;

#if WIN32
// 32bit machines.
int* pint = (int *)src;
int len = this.Length;
while(len > 0) {
hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0];
if( len <= 2) {
break;
}
hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ pint[1];
pint += 2;
len -= 4;
}
#else
int c;
char *s = src;
while ((c = s[0]) != 0) {
hash1 = ((hash1 << 5) + hash1) ^ c;
c = s[1];
if (c == 0)
break;
hash2 = ((hash2 << 5) + hash2) ^ c;
s += 2;
}
#endif
#if DEBUG
// We want to ensure we can change our hash function daily.
// This is perfectly fine as long as you don't persist the
// value from GetHashCode to disk or count on String A
// hashing before string B. Those are bugs in your code.
hash1 ^= ThisAssembly.DailyBuildNumber;
#endif
return hash1 + (hash2 * 1566083941);
}
}
}