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

推荐订阅源

Recorded Future
Recorded Future
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Troy Hunt's Blog
S
Security Archives - TechRepublic
S
Security @ Cisco Blogs
AI
AI
Schneier on Security
Schneier on Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
CERT Recently Published Vulnerability Notes
Spread Privacy
Spread Privacy
Help Net Security
Help Net Security
L
Lohrmann on Cybersecurity
The Hacker News
The Hacker News
Google DeepMind News
Google DeepMind News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Security Latest
Security Latest
T
Tor Project blog
P
Privacy International News Feed
The Last Watchdog
The Last Watchdog
L
LINUX DO - 最新话题
D
DataBreaches.Net
W
WeLiveSecurity
H
Help Net Security
L
LangChain Blog
B
Blog RSS Feed
Scott Helme
Scott Helme
Hacker News: Ask HN
Hacker News: Ask HN
C
Cisco Blogs
Cloudbric
Cloudbric
Application and Cybersecurity Blog
Application and Cybersecurity Blog
O
OpenAI News
I
InfoQ
GbyAI
GbyAI
Project Zero
Project Zero
Blog — PlanetScale
Blog — PlanetScale
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
G
GRAHAM CLULEY
T
The Blog of Author Tim Ferriss
酷 壳 – CoolShell
酷 壳 – CoolShell
Jina AI
Jina AI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 聂微东
美团技术团队
PCI Perspectives
PCI Perspectives
Y
Y Combinator Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

Hackaday

Downloadable Xbox Thumbstick Toppers Give Gamers Accessibility Options Wooden Piano Keys Hold Your Less-Wooden, Not-Piano Keys The Y2K Bug In BSD 2.11 That Survived 2000 IKEA Storage Box Just Happens To Make Great Printer Cover Building Your Own X-Ray Detector Screen Hackaday Links: June 14, 2026 Bavarian Court Tells Gemini It Can’t Be A Real Boy Until It Tells The Truth 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
Picking A CRC
Al Williams · 2026-06-15 · via 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.