गणना CRC32 हैश


14

क्रेडिट

यह चुनौती @miles से उत्पन्न हुई ।


एक फ़ंक्शन बनाएँ जो एक इनपुट स्ट्रिंग के CRC32 हैश की गणना करता है। इनपुट किसी भी लम्बाई का ASCII स्ट्रिंग होगा। आउटपुट उस इनपुट स्ट्रिंग का CRC32 हैश होगा।

व्याख्या

CRC32 और अन्य CRC की एल्गोरिथ्म अनिवार्य रूप से समान हैं, इसलिए यहां केवल CRC3 का प्रदर्शन किया जाएगा।

सबसे पहले, आपके पास जनरेटर बहुपद है, जो वास्तव में 4-बिट [एन + 1] पूर्णांक है (सीआरसी 32 में 33-बिट होगा)।

इस उदाहरण में, जनरेटर बहुपद है 1101

फिर, आपके पास हैशेड होने के लिए स्ट्रिंग होगी, जो इस उदाहरण में होगी 00010010111100101011001101

00010010111100101011001101|000 (1)    append three [n] "0"s
   1101                        (2)    align with highest bit
00001000111100101011001101|000 (3)    XOR (1) and (2)
    1101                       (4)    align with highest bit
00000101111100101011001101|000 (5)    XOR (3) and (4)
     1101                      (6)    align with highest bit
00000011011100101011001101|000 (7)    XOR (5) and (6)
      1101                     (8)    align with highest bit
00000000001100101011001101|000 (9)    XOR (7) and (8)
          1101                 (10)   align with highest bit
00000000000001101011001101|000 (11)   XOR (9) and (10)
             1101              (12)   align with highest bit
00000000000000000011001101|000 (13)   XOR (11) and (12)
                  1101         (14)   align with highest bit
00000000000000000000011101|000 (15)   XOR (13) and (14)
                     1101      (16)   align with highest bit
00000000000000000000000111|000 (17)   XOR (15) and (16)
                       110 1   (18)   align with highest bit
00000000000000000000000001|100 (19)   XOR (17) and (18)
                         1 101 (20)   align with highest bit
00000000000000000000000000|001 (21)   XOR (19) and (20)
^--------REGION 1--------^ ^2^

(21)जब क्षेत्र 1 शून्य होता है, जो 001सीआरसी 3 हैश का परिणाम होता है, तब प्राप्त शेष ।

ऐनक

  • जनरेटर बहुपद है 0x104C11DB7, या 0b100000100110000010001110110110111, या 4374732215
  • इनपुट स्ट्रिंग या पूर्णांक, या किसी अन्य उचित प्रारूप की एक सूची हो सकती है।
  • आउटपुट एक हेक्स स्ट्रिंग या सिर्फ एक पूर्णांक, या कोई अन्य उचित प्रारूप हो।
  • अंतर्निहित CRC32 हैश की गणना करने की अनुमति नहीं है।

लक्ष्य

लिए मानक नियम लागू होते हैं।

सबसे छोटा कोड जीतता है।

परीक्षण के मामलों

input         output      (hex)
"code-golf"   147743960   08CE64D8
"jelly"       1699969158  65537886
""            0           00000000

अगर मैं सही समझूं, तो यह बहुपद विभाजन modulo 2 कर रहा है और शेष को खोज रहा है, अर्थात XOR गुणा में मॉड का एनालॉग ।
xnor

1
हां। यह xnor modulo नहीं है, हालांकि, यह xor modulo है।
लीक नन

CRC32 के लिए, क्या आप सबसे पहले 31 ० है?
xnor

हाँ - - - - - - - - - -
लीक नून

1
@ केनीलाउ आप लोगों को चैट की तरह उनके नाम के साथ पिंग कर सकते हैं।
R

जवाबों:


12

इंटेल x86, 34 30 29 27 बाइट्स

ईएसआई में शून्य-समाप्त स्ट्रिंग का पता लेता है, और EBX में CRC लौटाता है:

31 db ac c1 e0 18 74 01 31 c3 6a 08 59 01 db 73 
06 81 f3 b7 1d c1 04 e2 f4 eb e7

Disassembly (एटी एंड टी सिंटैक्स):

00000000    xorl    %ebx, %ebx
00000002    lodsb   (%esi), %al
00000003    shll    $24, %eax
00000006    je      0x9
00000008    xorl    %eax, %ebx
0000000a    pushl   $8
0000000c    popl    %ecx
0000000d    addl    %ebx, %ebx
0000000f    jae     0x17
00000011    xorl    $0x4c11db7, %ebx
00000017    loop    0xd
00000019    jmp     0x2
0000001b

चार और बाइट्स को बचाने के लिए पीटर कॉर्ड्स के सुझावों को शामिल करना। यह एक कॉलिंग कन्वेंशन मानता है जहां प्रवेश के लिए स्ट्रिंग निर्देशों के लिए दिशा ध्वज को मंजूरी दी गई है।

पीटर फेर्री के सुझाव को शामिल करते हुए एक निरंतर लोड करने के लिए एक निरंतर लोड करने के लिए पुश शाब्दिक और पॉप का उपयोग करें।

पीटर फेरी के सुझाव को एक xorl %eax, %ebxनिर्देश के दूसरे बाइट में कूदने के लिए शामिल करना, जो कि एक retlनिर्देश है, जो रूट के इंटरफेस को बदलने के साथ-साथ लंबाई के बजाय शून्य-टर्मिनेटेड स्ट्रिंग लेने के लिए संयुक्त है, जिससे कुल दो बाइट्स बचते हैं।


एक कॉलिंग कन्वेंशन का उपयोग करें जिसमें प्रवेश पर दिशा ध्वज को साफ़ करने की आवश्यकता होती है, इसलिए आप cldइन्स को बचा सकते हैं (जैसे मैंने अपने adler32 उत्तर में किया था )। क्या एएसएम के जवाब के लिए पूरी तरह से मनमानी कॉलिंग कन्वेंशन की अनुमति देना सामान्य अभ्यास है?
पीटर कॉर्ड्स

वैसे भी, ऐसा लगता है कि आपका कोड x86-64 मशीन कोड के रूप में काम करेगा, और आप गणना करने के लिए x86-64 SysV x32 कॉलिंग कन्वेंशन का उपयोग कर सकते हैं ediऔर पॉइंटर अंदर esi(शायद शून्य-विस्तारित नहीं है, इसलिए हो सकता है कि चीजों को ठग लें और आवश्यकता हो 64 बिट शून्य-विस्तारित सूचक)। (x32 इसलिए आप 32 बिट पॉइंटर गणित का सुरक्षित रूप से उपयोग कर सकते हैं, लेकिन फिर भी रजिस्टर-आर्ग्स कॉलिंग कन्वेंशन है। चूंकि आप उपयोग नहीं करते हैं inc, इसलिए लंबे मोड में कोई नकारात्मक पहलू नहीं है।)
पीटर कॉर्ड्स

क्या आपने edxबाइट-उलट क्रम में रखने पर विचार किया ? bswap edxकेवल 2 बी है। shr %edx2B है, साथ ही आपकी बाईं-शिफ्ट भी add %edx,%edx। यह शायद सहायक नहीं है; जब तक यह अधिक अनुकूलन को सक्षम नहीं करता है, आप के लिए 3 बी बचाते हैं shl $24, %eax, लेकिन आप xor %eax,%eaxशुरुआत में और bswap %edxअंत में 4 बी खर्च करते हैं । ज़ीरिंग ईएक्सएक्स आपको cdqशून्य का उपयोग करने देता है %edx, इसलिए कुल मिलाकर यह एक धोने है। यह बेहतर प्रदर्शन करेगा, हालांकि: यह लेखन से हर पुनरावृत्ति पर आंशिक-रजिस्टर स्टाल / मंदी से बचा जाता है alऔर फिर eaxshl के साथ पढ़ना । : पी
पीटर कॉर्ड्स

1
एडलर -32 प्रश्न के साथ भ्रमित हो गया, जिसकी लंबाई सीमा है। इस प्रश्न की स्पष्ट लंबाई सीमा नहीं है।
मार्क एडलर

1
PCLMULQDQ निर्देश के साथ इसे कम करने का एक तरीका हो सकता है। हालाँकि इसके उपयोग में बहुत अधिक स्थिरांक की आवश्यकता होती है, इसलिए संभवतः नहीं।
मार्क एडलर


4

रूबी, 142 बाइट्स

अनाम फ़ंक्शन; इनपुट के रूप में एक स्ट्रिंग लेता है, एक पूर्णांक देता है।

->s{z=8*i=s.size;r=0;h=4374732215<<z
l=->n{j=0;j+=1 while 0<n/=2;j}
s.bytes.map{|e|r+=e*256**(i-=1)};r<<=32
z.times{h/=2;r^=l[h]==l[r]?h:0}
r}

2
क्या आप अपना नाम बदल सकते हैं ताकि लोग हमें पहचान सकें? XD
लीक नून

2
@ केनीलाऊ क्या आपको इतना अशिष्ट होना चाहिए ... ठीक है ठीक है
मूल्य इंक

मैं सिर्फ xd मजाक कर रहा था
लीक नून

4

जेली , 23 बाइट्स

ḅ⁹Bµ4374732215B×ḢḊ^µL¡Ḅ

इनपुट पूर्णांकों की सूची के रूप में है। इसे ऑनलाइन आज़माएं! या सभी परीक्षण मामलों को सत्यापित करें

यह काम किस प्रकार करता है

जबकि जेली में बिटवाइज़ एक्सओआर है, इनपुट को ज़ीरो के साथ पैडिंग करके और बहुपद को सबसे महत्वपूर्ण बाइनरी अंक के साथ संरेखित करना इस दृष्टिकोण को बनाता है, जो बिट्स की सूची का उपयोग करता है, एक बालक छोटा।

ḅ⁹Bµ4374732215B×ḢḊ^µL¡Ḅ  Main link. Argument: A (list of bytes)

ḅ⁹                       Convert A from base 256 to integer.
  B                      Convert the result to binary, yielding a list.
   µ                     Begin a new, monadic chain. Argument: B (list of bits)
    4374732215B          Convert the integer to binary, yielding a list.
                Ḣ        Pop and yield the first, most significant bit of B.
               ×         Multiply each bit in the polynomial by the popped bit.
                 ^       Compute the element-wise XOR of both lists.
                         If one of the lists is shorter, the elements of the other
                         lists do not get modified, thus avoiding the necessity
                         of right-padding B with zeroes.
                  µ      Convert the previous chain into a link.
                   L¡    Execute the chain L times, where L is the number of bits
                         in the original bit list.
                     Ḅ   Convert from binary to integer.


3

सीजेएम, 37 36 बाइट्स

q256b32m<{Yb4374732215Yb.^Yb_Yb32>}g

इसका परीक्षण यहां करें।

व्याख्या

q               e# Read input.
256b            e# Convert to single number by treating the character codes
                e# as base-256 digits.
32m<            e# Left-shift the number by 32 bits, effectively appending 32
                e# zeros to the binary representation.
{               e# While the condition on top of the stack is truthy...
  Yb            e#   Convert the number to base 2.
  4374732215Yb  e#   Convert the polynomial to base 2.
  .^            e#   Take the bitwise XOR. If the number is longer than the
                e#   polynomial, the remaining bits will be left unchanged.
  Yb            e#   Convert the list back from base 2, effectively stripping
                e#   leading zeros for the next iteration.
  _             e#   Duplicate the result.
  Yb            e#   Convert back to base 2.
  32>           e#   Remove the first 32 bits. If any are left, continue the loop.
}g

q256bYb_,{(4374732215Ybf*1>.^}*Ybकुछ बाइट्स बचाता है।
डेनिस

@ डेनिस वास्तव में चतुर है, इसे एक अलग जवाब देने के लिए स्वतंत्र महसूस करें। :)
मार्टिन एंडर

3

पायथ, 28 बाइट्स

uhS+GmxG.<C"Á·"dlhG.<Cz32

इसे ऑनलाइन आज़माएँ: प्रदर्शन या टेस्ट सूट

स्पष्टीकरण:

uhS+GmxG.<C"..."dlhG.<Cz32   implicit: z = input string
                      Cz     convert to number
                    .<  32   shift it by 32 bits
u                            apply the following expression to G = ^,
                             until it get stuck in a loop:
     m           lhG            map each d in range(0, log2(G+1)) to:
          C"..."                   convert this string to a number (4374732215)
        .<      d                  shift it by d bits
      xG                           xor with G
   +G                           add G to this list
 hS                             take the minimum as new G

2

जावास्क्रिप्ट (ईएस 6), 180 बाइट्स

f=(s,t=(s+`\0\0\0\0`).replace(/[^]/g,(c,i)=>(c.charCodeAt()+256*!!i).toString(2).slice(!!i)))=>t[32]?f(s,t.replace(/.(.{32})/,(_,m)=>(('0b'+m^79764919)>>>0).toString(2))):+('0b'+t)

एक 33-बिट XOR ऑपरेटर की कमी, या यहां तक ​​कि एक अहस्ताक्षरित 32-बिट XOR ऑपरेटर की कमी है।


1

CJam, 33 बाइट्स

q256bYb_,{(4374732215Ybf*1>.^}*Yb

इनपुट एक स्ट्रिंग के रूप में है। इसे ऑनलाइन आज़माएं!

यह काम किस प्रकार करता है

q                                  Read all input from STDIN.
 256bYb                            Convert it from base 256 to base 2.
       _,{                   }*    Compute the length and repeat that many times:
          (                          Shift out the first bit.
           4374732215Yb              Convert the integer to base 2.
                       f*            Multiply each bit by the shifted out bit.
                         1>          Remove the first bit.
                           .^        Compute the element-wise XOR of both lists.
                                     If one of the lists is shorter, the elements
                                     of the other lists do not get modified, thus
                                     avoiding the necessity of right-padding B with
                                     zeroes.
                               Yb  Convert the final result from base 2 to integer.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.