TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Show HN: Super Simple CRC32 Implementation

14 pointsby dch827 months ago
I written this as a little programming exercise in C

7 comments

rurban7 months ago
A normal table-based crc32. Since we don't see the generator, we cannot see the polynom. You usually put the generator in the code
Someone7 months ago
I suggest you write a few test cases to verify that it works reliably. I have my doubts about that, given this code fragment:<p><pre><code> &#x2F;&#x2F; stop hashing when there is nothing left to hash while (scanf(&quot;%d&quot;, &amp;ch) != EOF) { &#x2F;&#x2F; get the current byte ch = getchar();</code></pre>
评论 #41988053 未加载
评论 #41987374 未加载
jart7 months ago
If you don&#x27;t want a hard coded table, you could always do this.<p><pre><code> unsigned kCastagnoli[256]; void InitializeCrc32(unsigned table[256], unsigned polynomial) { unsigned d, i, r; for (d = 0; d &lt; 256; ++d) { r = d; for (i = 0; i &lt; 8; ++i) r = r &gt;&gt; 1 ^ (r &amp; 1 ? polynomial : 0); table[d] = r; } } unsigned Castagnoli(unsigned h, unsigned long w, long n) { long i; static int once; if (!once) { InitializeCrc32(kCastagnoli, 0x82f63b78); once = 1; } for (i = 0; i &lt; n; ++i) { h = h &gt;&gt; 8 ^ kCastagnoli[(h &amp; 255) ^ (w &amp; 255)]; w &gt;&gt;= 8; } return h; } </code></pre> That does the same thing as the crc32 instructions in x86.
评论 #42030591 未加载
palsecam7 months ago
FTR, an implementation in “low-level” JavaScript:<p><pre><code> &#x2F;** Precomputed CRC-32 lookup table for half-bytes (aka “nibbles”). * Trade more compute time for less memory and less code to transmit. * @see https:&#x2F;&#x2F;create.stephan-brumme.com&#x2F;crc32&#x2F;#half-byte *&#x2F; const CRC32_NIBBLE_TABLE = new Uint32Array([ 0, 0x1DB71064, 0x3B6E20C8, 0x26D930AC, 0x76DC4190, 0x6B6B51F4, 0x4DB26158, 0x5005713C, 0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C, 0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C ]); &#x2F;** @return {number} CRC-32 (polynomial 0x04C11DB7) of the input data. * @param {!BufferSource} data The input data. * @param {number=} previousValue The previous CRC value, if resuming a computation. * @see https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cyclic_redundancy_check *&#x2F; function crc32(data, previousValue = 0) { const bytes = ArrayBuffer.isView(data) ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : new Uint8Array(data); let crc = ~previousValue; for (let i = 0; i &lt; bytes.length; i++) { crc = (crc &gt;&gt;&gt; 4) ^ CRC32_NIBBLE_TABLE[0x0f &amp; (crc ^ bytes[i])]; crc = (crc &gt;&gt;&gt; 4) ^ CRC32_NIBBLE_TABLE[0x0f &amp; (crc ^ (bytes[i] &gt;&gt; 4))]; } return ~crc; } </code></pre> From <a href="https:&#x2F;&#x2F;GitHub.com&#x2F;PaulCapron&#x2F;pwa2uwp&#x2F;blob&#x2F;master&#x2F;src&#x2F;zip.js">https:&#x2F;&#x2F;GitHub.com&#x2F;PaulCapron&#x2F;pwa2uwp&#x2F;blob&#x2F;master&#x2F;src&#x2F;zip.js</a>
fargle7 months ago
this simply matches the `crc_reflected()` in section 18 of &quot;A Painless Guide to CRC Error Detection Algorithms&quot; [1] with hardcoded init and final xor&#x27;s to match one specific CRC-32 spec. nothing wrong with that, but it isn&#x27;t original at all either.<p>i recommend the &quot;painless guide&quot; for anyone constructing CRC algorithms in software. it breaks down the entire algorithm, including various trade-offs and choices, as well as for different polynomials and other parameters.<p>then you also have the catalogs of parameters [2] and [3]<p>[1] <a href="https:&#x2F;&#x2F;www.zlib.net&#x2F;crc_v3.txt" rel="nofollow">https:&#x2F;&#x2F;www.zlib.net&#x2F;crc_v3.txt</a> [2] <a href="https:&#x2F;&#x2F;reveng.sourceforge.io&#x2F;crc-catalogue&#x2F;" rel="nofollow">https:&#x2F;&#x2F;reveng.sourceforge.io&#x2F;crc-catalogue&#x2F;</a> [3] <a href="https:&#x2F;&#x2F;users.ece.cmu.edu&#x2F;~koopman&#x2F;crc&#x2F;" rel="nofollow">https:&#x2F;&#x2F;users.ece.cmu.edu&#x2F;~koopman&#x2F;crc&#x2F;</a>
tzs7 months ago
OT: I copied the error detection code that AcuRite uses in their temperature sensors for use in my rain gauge. (I got the code by taking a look at the decoder for AcuRite temperature sensors that is included in rtl_433).<p>At the time I thought it was a CRC, but later I realized that it isn&#x27;t. I&#x27;ve been trying to find out what the name is for that kind of code but have failed. I wonder if anyone here happens to know?<p>Here is the code:<p><pre><code> byte check_code(byte const message[], unsigned nbytes, byte gen, byte key) { byte sum = 0; for (unsigned k = 0; k &lt; nbytes; ++k) { byte data = message[k]; for (int i = 7; i &gt;= 0; --i) { if ((data &gt;&gt; i) &amp; 1) sum ^= key; if (key &amp; 1) key = (key &gt;&gt; 1) ^ gen; else key = (key &gt;&gt; 1); } } return sum; } </code></pre> I thought it was a CRC because I saw it shifting and saw it xoring when it shifted out a 1. That&#x27;s quite reminiscent of the method of CRC computation that treats bit strings as representing polynomials in GF(2) and computes the CRC by doing polynomial division essentially the same way we would do it by hand.<p>But when computing a CRC that way what you xor the data with is a constant (the representation of the generator polynomial). In the algorithm above the constant is not xor&#x27;ed with the data. In fact nothing is xor&#x27;ed with the data.<p>The constant, named &#x27;gen&#x27; which is another reason I thought at first it was a CRC, is actually the feedback polynomial for a Galois linear feedback shift register (LFSR), which is seeded with the &#x27;key&#x27; parameter. That LFSR generates one byte for every bit of the message, and the bytes that are generated for the message bits that are set are xor&#x27;ed together, and it is the result of that that is the check code.<p>In higher level terms the general approach it is using can be described like this in a Pythonish pseudocode, assuming PRNG() is a psuedorandom byte generator, and seed_PRNG() is a function to seed that generator:<p><pre><code> def check_code(message, key): sum = 0 seed_PRNG(key) foreach bit in message: next_random = PRNG() if bit == 1: sum ^= next_random return sum </code></pre> Pick a Galois LSFR with feedback polynomial &#x27;gen&#x27; as your PRNG and that matches the AcuRite code.
Sianko7 months ago
So there are many different flavors of crc32. Usually you can always change the initialization value. This algorithm is only one use case.<p>Check this table out <a href="https:&#x2F;&#x2F;www.crccalc.com&#x2F;?crc=123456789&amp;method=&amp;datatype=0&amp;outtype=0" rel="nofollow">https:&#x2F;&#x2F;www.crccalc.com&#x2F;?crc=123456789&amp;method=&amp;datatype=0&amp;ou...</a>
评论 #42029613 未加载