x86 मशीन कोड, 46 बाइट्स
Hexdump:
57 53 33 c0 33 ff f6 01 0f 75 15 6a 0a 5b 99 f7
f3 6b ff 0a 03 fa 33 c0 38 01 75 0f 97 5b 5f c3
69 c0 26 2b aa 6e 32 01 c1 e8 02 41 eb d8
यह एक fastcallफ़ंक्शन है - स्ट्रिंग में एक पॉइंटर को प्राप्त करता है ecx, और परिणाम को वापस करता है eax।
हैशिंग फ़ंक्शन एक जादुई संख्या से गुणा 1856645926करता है, एक XORइनपुट बाइट के साथ करता है , और 2 बिट्स द्वारा सही बदलता है।
Noclobber रजिस्टरों को सहेजना और पुनर्स्थापित करना ( ediऔर ebx) 4 बाइट्स लेता है , लेकिन मुझे इसे लागू करने के लिए अधिक कुशल तरीका नहीं मिला। निरंतर 10 में भंडारणebx विशेष रूप से कष्टप्रद था!
संबंधित कोड बाइट्स के साथ डिसआर्डर
57 push edi ; edi = result
53 push ebx ; we use ebx to store the constant 10
33 C0 xor eax,eax
33 FF xor edi,edi
myloop:
F6 01 0F test byte ptr [ecx],0Fh ; check for end of word
75 15 jne myhash
6A 0A push 0Ah
5B pop ebx
99 cdq ; prepare 64-bit dividend in edx:eax
F7 F3 div eax,ebx ; find the remainder of division by 10
6B FF 0A imul edi,edi,0Ah
03 FA add edi,edx ; update the result
33 C0 xor eax,eax ; reset the hash temporary variable
38 01 cmp byte ptr [ecx],al ; check for end of input (here al=0)
75 0F jne mycontinue
97 xchg eax,edi ; set the return register
5B pop ebx ; restore registers
5F pop edi ; restore registers
C3 ret
myhash:
69 C0 26 2B AA 6E imul eax,eax,6EAA2B26h ; hashing...
32 01 xor al,byte ptr [ecx] ; hashing...
C1 E8 02 shr eax,2 ; hashing...
mycontinue:
41 inc ecx ; next input byte
EB D8 jmp myloop
समतुल्य सी कोड:
int doit(const char* s)
{
int result = 0;
unsigned temp = 0;
while (true)
{
int c = *s++;
if ((c & 15) == 0)
{
temp %= 10;
result = result * 10 + temp;
temp = 0;
if (c == 0)
break;
else
continue;
}
temp *= 1856645926;
temp ^= c;
temp >>= 2;
}
return result;
}