惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
The Register - Security
The Register - Security
G
Google Developers Blog
罗磊的独立博客
WordPress大学
WordPress大学
L
LangChain Blog
博客园 - 三生石上(FineUI控件)
Recorded Future
Recorded Future
Microsoft Azure Blog
Microsoft Azure Blog
Google DeepMind News
Google DeepMind News
大猫的无限游戏
大猫的无限游戏
MongoDB | Blog
MongoDB | Blog
小众软件
小众软件
Recent Announcements
Recent Announcements
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
云风的 BLOG
云风的 BLOG
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Full Disclosure
The Cloudflare Blog
B
Blog RSS Feed
S
Schneier on Security
T
Tenable Blog
人人都是产品经理
人人都是产品经理
Engineering at Meta
Engineering at Meta
T
Tor Project blog
N
Netflix TechBlog - Medium
T
Threatpost
NISL@THU
NISL@THU
Stack Overflow Blog
Stack Overflow Blog
N
News | PayPal Newsroom
N
News and Events Feed by Topic
aimingoo的专栏
aimingoo的专栏
博客园 - 叶小钗
P
Privacy & Cybersecurity Law Blog
C
CERT Recently Published Vulnerability Notes
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Privacy International News Feed
博客园 - 【当耐特】
Help Net Security
Help Net Security
The Hacker News
The Hacker News
Hugging Face - Blog
Hugging Face - Blog
TaoSecurity Blog
TaoSecurity Blog
S
Secure Thoughts
C
Cisco Blogs
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events

Blog – Hackaday

Why Not Yserver? It’s Xserver, But Rust-y. OpenCAL: Computed Axial Lithographic 3D Printing For Everyone Is A CS Degree DOA Thanks To LLMs? IEEE Says TBD. Double The VRAM Of An RTX 3070 The Pacemaker Patch Robot Chess But Each Piece Is A Small Robot Bambuddy Says Bye To Bambu Lab Cloud Services Converting A Scanning Electron Microscope Into A TEM Is Surprisingly Easy Custom Watch Is On The Case Patterns Everywhere Behold A 60 Hz Refresh Rate E-ink Monitor GentleOS, A Simple OS For Your Old PC Deeply Optimized MSX Emulation On ESP32-S3 With VGA Output Homebrew Macropad Looks Good The Air Position Indicator For The B-29 Building A 1:150 Scale Toyota ProBox Micro Remote Control Car Adding Weight To A 3D Print With Plaster Of Paris, Cleanly Hackaday Podcast Ep 373: GPS, Danger In Space, And Robby The Robot A Peek Inside The Secret Lagercrantz Suitcase Radio This Week In Security: Microsoft On Microsoft, Register Your Domains, Linux On ARM, And FreeBSD Joins The File Cache Club Glue-in Hinge Design Tries Something Different The Hackaday Communicator Badge, Re-Imagined With New Firmware Amiga 1232 Storm CD Packs Every Upgrade Into One Wedge So Many Analog To Digital Converters Repairing A Pair Of Voodoo 2 GPUs For Some SLI Action AI The Truly Environmentally Friendly Way Evidence For Water Vapor Plumes On Europa Vanishes In Re-Analysis Mechanical Stability For Your Coils 3D Printed Hose Sprayer Sets Phasers To Suds The Merits Of Comment-Driven Development As Counterweight To TDD Building A Desktop Catalytic Cracker Process 4 Billion Pixels Per Second From 16 DIY Cameras For The Best V-Tubing Rig Ever 3D Printing A Miniature CoreXY Printer An Unlikely Host For An 8080 Emulator Using Brand New NiMH Cells After Sitting 12 Years Unused Investigating The S3 Virge’s Reputation As A 3D Decelerator Card Over-Engineering An FDM Spool Holder From Prusa Mk4S Remains As It Turns Out, There’s More Than One Cassette Mechanism Being Made After All Using Windows 11 On An LGA 775 PC With AGP Videocard Hackaday Podcast Episode 372: PopTubers, Shifty Semiconductors, And Shelving Shelf Labels An Ethernet WiFi Router on a Pi Pico 2W This Week In Security: Messing With AI, 7Zip And Notepad++ Vulnerabilities, HTTP2 Bomb, And More Using Electrolysis For More Than Just Generating Hydrogen Vintage Turntable Gets Brain Transplant And Home Assistant Integration Connecting Your Car To Home Assistant Microsoft Claims 20 Second Qubits If You Want To Hack Me, Come In Through The Speaker Ways To Embed Magnets In 3D Prints And Not Ruin Printers An RGB Keyboard For Your Hackaday Communicator Badge The World’s First GPIB Speech Synthesizer, And It’s For A GRiD Compass Ask Hackaday: How Do You Feel About Electronic Shelf Labels? Make Your Ceiling Disappear With ADS-B And Short-Throw Projector Fixing A Nintendo Game Boy Clone That Runs Too Fast Web-Based Control For A CB Radio Distilling Stale Gasoline To Make It Usable Again DIY Ceramic Circuit Boards Surely Count As Solarpunk Texas Instruments Changes The NE5532 And Others Into Incompatible Versions Deltarune’s Tenna Brought To Life Linux Fu: Fake Webcams, GUI Edition Hydraulic Drive For Your Lawn Tractor But Just What Is This ‘Artificial Intelligence’? Game Dodecahedron Runs AArch64 Assembly A Diffraction Grating Makes This Clock Readable Turning An Old 3D Printer Into A Vinyl Cutter For Cheap A High-Vacuum Controller For An Eventual Electron Microscope Does Your Terminal Speak Morse? This One Does From Scrappy Pallet Wood To Fancy Tea Tray The 2026 EMF Badge Arrives, With An Add-On. As Expected, It’s Familiar Linux Fu: Taming Strace STM32 Handheld Has OpenGL And All The Classics Jenny’s Daily Drivers: Microsoft Windows 11 Using A Mirror To 3D Scan Both Sides Of An Object At Once Cookies, Baked The 3D Printer Way Restoring Apple’s Terrible But Awesome IBook Laptop After The Dust Settles: Building Pebble Apps Bilingual E-paper News Feed Helps Brush Up Language Skills On The Wisdom Of Replacing A NiMH Module In A Prius Battery Pack Know Your Food: Cheesemaking Like A Wire Bender, But For Pop Tubes Revisiting Making Your Own Internet Router In 2026 Reverse Engineering A Rock Bottom NES Clone Classically-named Argus Robot Is Terminator Meets Tumbleweed Making a Zippy FDM Printer out of Wood Off-Grid OCR Server Powered By IPhone Hackaday Links: May 31, 2026 A Camera Viewfinder Makes A Great TV 4-bit Relay Logic Counter Begs To Have Its Buttons Pushed Loading Sega Genesis Games Off A Vinyl Record Ebike Display Uses Reflective LCD Modern Graphics Via DisplayLink For Your ISA-Era PC The Final Steps To A Sub-Minute Benchy Poking Around With JTAG On A Guitar Amp Keychain GameCube Controller Made Functional Breaking Enigma With An FPGA, Just Like At Bletchley Park The Uncooperative Mirror Will Not Help You Testing Various Ways To Waterproof FDM Printed Parts Cheap Yellow Display With Boosted PSRAM Turned Snazzy Emulator Station It’s Another Pi Handheld. But It’s A Really Good One Take The Reins Of This Unique Controller Be Your Own Oil Company With Desktop Fischer-Tropsch Process
Picking A CRC
Al Williams · 2026-06-15 · via Blog – Hackaday

You send a file, but how do you know it arrived intact? In other words, how do you know that it didn’t get cut off, garbled, or changed somehow? Simplistically, you could just add up all the bytes in the file — a checksum — and send that along with the file. You compute the checksum when you know the file is good, and the receiver can compare the checksum to see if they match.

However, a simple addition doesn’t catch certain classes of errors, which is why there are better checksum algorithms that, for example, wrap the carry bit around or otherwise modify files with common errors so they produce different checksums. There are two problems with checksums. First, no matter how much you modify the algorithm, the chances that two files produce the same checksum are pretty high. Especially with common error patterns.

For example, assume a very simple algorithm that simply adds the bytes and discards any carry. If a file contains 0x80, 0x80, those numbers essentially cancel each other out. If you replace them with 0, 0, you’ll get the same checksum. To some degree, using anything other than a second copy of the entire file will have this problem — some corruption goes undetected — but you want to minimize the number of times that happens.

The other problem is that a checksum by itself doesn’t let you correct anything. You know the data is bad, but you don’t know why. If you think about it, the simplest checksum is a parity bit on a byte: odd parity is simply summing all the bits together. If the parity bit doesn’t match, you know the byte is bad, but you don’t know why. Any even number of errors goes undetected, but I am sure one-, three-, five-, or seven-bit errors will get caught.

People invent better error-checking codes by devising schemes that can promise they can detect a certain number of bit flips and, at least in some cases, correct them. One of these is the cyclic redundancy check (CRC). It is easy to think of the CRC as a “strong checksum,” but it actually works differently. What’s more, there isn’t just a single CRC algorithm. You have to select or design a particular algorithm based on your needs. Most people pick a “named” implementation like CCITT or Ethernet and assume it must be the best. It probably isn’t.

A CRC is a checksum in the broad sense: you feed it a message, and it gives you a small value that you append, store, or compare later. But unlike a simple additive checksum, a CRC is based on polynomial division over GF(2), which is a fancy way of saying “divide using XOR instead of carries.” That detail matters. It gives CRCs very strong guarantees against common classes of errors, provided you choose the right polynomial for the job. That’s the key. You must choose the right polynomial.

The Polynomial Machine

A CRC treats your message as a long binary polynomial. For example, the byte stream is interpreted as a sequence of coefficients: each bit is either present or absent. The CRC algorithm divides the message polynomial, after shifting it by the CRC width, by a generator polynomial. The remainder is the CRC.

In normal arithmetic, division involves subtraction and carries. In CRC arithmetic, subtraction is XOR. That is why CRC code often looks like this:


if (crc & topbit)
crc = (crc << 1) ^ poly;
else
crc <<= 1;

That loop is implementing polynomial long division, one bit at a time. The generator polynomial is the magic number. For a 16-bit CRC, the polynomial has degree 16. For a 32-bit CRC, degree 32. You will usually see it written as a hex constant, such as 0x1021 for CRC-16/CCITT or 0x04C11DB7 for the classic Ethernet/ZIP/PNG CRC-32. But the polynomial is not just an arbitrary constant. It determines what error patterns the CRC is guaranteed to detect.

What CRCs Catch

A well-chosen CRC can guarantee detection of all single-bit errors, many multi-bit errors, all burst errors up to a certain length, and a very high percentage of longer random errors. The key metric is Hamming distance, often abbreviated HD. If a CRC has HD=4 for messages up to a certain length, it detects all 1-, 2-, and 3-bit errors in messages of that length.

That last qualifier is important. CRC strength is not just “16-bit CRC good, 32-bit CRC better.” It depends on the maximum message length. A polynomial that is excellent for 32-byte embedded packets may be mediocre for kilobyte-size messages. A polynomial standardized decades ago may be familiar but not optimal.

[Philip Koopman’s] work at Carnegie Mellon is the go-to reference here. [Koopman] and [Chakravarty’s] paper on CRC polynomial selection for embedded networks specifically looked for good CRC polynomials for short embedded messages, and [Koopman’s] “Best CRC Polynomials” tables list polynomials by width and Hamming-distance performance. The important takeaway is that many standard polynomials were chosen for historical reasons, not because they are mathematically best for your packet size.

There are plenty of videos that explain CRC, but if you are going to watch a video, you might as well pick one of the many from [Phil Koopman] himself, like the one below.

Famous Does Not Mean Optimal

Take CRC-16/CCITT, polynomial 0x1021. It is found everywhere: telecom, embedded examples, and bootloaders. It is not a terrible polynomial, but it is not automatically the best 16-bit choice. [Koopman’s] tables include other 16-bit polynomials with better Hamming-distance behavior over useful embedded-message lengths.

Likewise, classic CRC-32 using polynomial 0x04C11DB7 is deeply entrenched because of Ethernet, ZIP, gzip, and PNG. But CRC-32C, the Castagnoli polynomial, is often a better general-purpose choice. It has excellent error detection properties over common message lengths and is also supported by hardware instructions on many CPUs. Intel added CRC32 instructions with SSE4.2, and ARM AArch64 also includes CRC acceleration for CRC-32 and CRC-32C.

Of course, standards matter if you have to meet the standard. But if you are designing a new private protocol between your sensor board and your controller, blindly copying the first CRC-16 example from the Internet is not engineering. Pick a polynomial based on your packet length and your risk model.

The Practical Embedded View

For very small messages, even an 8-bit CRC may be adequate. For moderate packets, a good 16-bit CRC is often enough. For firmware images or large records, 32 bits is more reasonable. The point is not to use the biggest CRC you can tolerate. The point is to choose a CRC width and polynomial that give the desired detection strength for your longest protected message.

Also, remember what a CRC does not do. It is not cryptographic. It does not stop malicious tampering. The point of a CRC is to detect accidental corruption, not protect against sophisticated hacking attempts.

Real-world CRC definitions also include bit reflection, initial value, final XOR value, and sometimes byte order conventions. Two CRCs can use the same polynomial and still produce different answers because those parameters differ. That is a common embedded debugging trap. Someone says “CRC-16,” and both sides implement different CRC-16s. CRC-16/IBM, CRC-16/CCITT-FALSE, CRC-16/XMODEM, CRC-16/KERMIT, and CRC-16/MODBUS are not interchangeable.

If you specify a CRC in a protocol document, include at least the width, the polynomial (which can be represented in different formats, by the way), the initial value, if you use reflection on the input or output, and any value to XOR the output with. It is also a great idea to include the computed checksum for ASCII “123456789” so anyone can compare their algorithm to yours.

If you are working with Linux systems, be sure to look at the cksum program which can use several CRC algorithms or other methods like sha1 and other digest-style methods.

Efficiency

Computing CRCs a bit at a time is compact, but it costs eight loop iterations per byte. In some cases, that’s ok, but for performance, you want a table if you can afford the memory. For a 16-bit CRC, the table is only 512 bytes and can be generated at compile time, if desired.

Many CPUs have CRC peripherals. Use them, but read the fine print to make sure they can handle your desired CRC. It is often a good idea to check a hardware implementation against a known-good software implementation before you send it out into the wild. You can do many CRC tests using an online tool. Of course, there are several out there.

Choosing a CRC Today

For a new embedded protocol, define the maximum length of data you need to check. Then decide how many bits of overhead you can afford. Then head to Koopman’s tables to pick a polynomial with good Hamming-distance performance for that length.

The CRC has been around for a long time. But it isn’t just something you grab off the shelf. You need to plan and understand the ramifications of picking different polynomials.

CRCs aren’t the only game in town. Credit card numbers, for example, use check digits. There are other ways you can identify and, in some cases, zap bit errors, too.