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

推荐订阅源

AI
AI
Scott Helme
Scott Helme
W
WeLiveSecurity
N
News | PayPal Newsroom
G
GRAHAM CLULEY
SecWiki News
SecWiki News
V2EX - 技术
V2EX - 技术
Security Latest
Security Latest
H
Heimdal Security Blog
L
LINUX DO - 最新话题
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Palo Alto Networks Blog
Simon Willison's Weblog
Simon Willison's Weblog
PCI Perspectives
PCI Perspectives
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
Spread Privacy
Spread Privacy
T
Troy Hunt's Blog
V
Vulnerabilities – Threatpost
罗磊的独立博客
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
T
The Blog of Author Tim Ferriss
阮一峰的网络日志
阮一峰的网络日志
Martin Fowler
Martin Fowler
The Hacker News
The Hacker News
C
Cisco Blogs
T
Tor Project blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The Register - Security
The Register - Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Privacy & Cybersecurity Law Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
Security Affairs
T
Tenable Blog
V
Visual Studio Blog
C
Check Point Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
美团技术团队
月光博客
月光博客
J
Java Code Geeks
量子位
Vercel News
Vercel News
I
Intezer
博客园 - 聂微东
Know Your Adversary
Know Your Adversary
aimingoo的专栏
aimingoo的专栏

Comments for Hackaday

AI The Truly Environmentally Friendly Way News Sites Are Blocking Internet Archive Over AI Scraping Fears How The 2020s Chip Crisis Led To A Buggy Saleae Analyzer In 2026 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 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 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 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 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’? 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 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 Comment on A Special Type of Mower For Rocky Fields by Chris Maple 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 ESP-Osito Eschews Retrocomputing For Modern Code On Modern, Equivalent Hardware A Modern Web Browser For Classic Mac OS Hackaday Podcast Episode 371: Space Computers, Spy Phones, And So Long CHU This Week In Security: Ubiquiti Fixes, And FreeBSD Joins The Club You Don’t Want To Join When Is An Apple Laptop Not A Macbook? When It’s An Apple II Linux Distributions And Who Is Responsible For The Software Autopsy Of A Failed Vintage Carbon Resistor Hunting Submarines Via Gravity Is A Tough Errand So Long, CHU, And Thanks For All The Time Signals A Bicycle Built On An Italian Renaissance Tech Base Linux Fu: The Bluetooth Regression Remember When Flash Drives Were Going To Make Your PC Faster? Putting Version 7.1 Of The Direct Granules FDM Extruder Through Its Paces Tech In Plain Sight: The Mechanics Of String Trimmers Between-Device Sharing Still Sucks Salvaged VFDs In Nixie-Like Clock Mod This IKEA Lamp Into Smart Lighting For Not A Lot Building And Testing A Turbine Driven Hydro Generator Tearing Down Walmart’s $12 Keychain Camera Biohack Your Way To Lactose Tolerance (Through Suffering) Liberating AirPods With Bluetooth Spoofing It’s Hard To Make A (Good) Oscillator Rudolph’s Sleigh On A North Pole PCB This Typewriter Types Toast Beating Bitlocker In 43 Seconds Using An Old Smartphone In Place Of A Raspberry Pi Working Model Reveals Amazing Engineering Of Webb’s Mirror Actuators Electric Vehicle 1900’s Style: New Leases On Old Tech Forth: The Hacker’s Language
Picking A CRC
Al Williams · 2026-06-15 · via Comments for 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.