CRC是什麼?用0與1的除法找出傳輸錯誤的原理

約 11 分鐘 · 更新:2026年10月23日

CRC(循環冗餘檢查)是從資料算出簡短的檢查值一起傳送,再由接收端重新計算來發現錯誤的機制。計算的是只用0和1的「除法的餘數」,並以XOR代替減法,所以用小小的電路就能快速算出。有線網路、Wi-Fi、ZIP檔等都會用到,偶然發生的錯誤幾乎不會漏掉。不過,它無法更正錯誤,也無法識破蓄意的竄改。

這篇文章可以了解

  • 用來發現錯誤的「檢查值」的概念
  • 同位檢查和檢查碼(checksum)會漏掉的錯誤
  • 用只有0和1的除法,手算求出CRC的方法
  • 計算CRC的電路原理
  • CRC一定能發現的錯誤,以及CRC做不到的事

先備知識:二進位,以及XOR(互斥或:2個輸入不同時輸出1的運算)。兩者都在「電腦怎麼用0和1計算?」中說明。

生活中的例子

你是否曾經在打開下載的ZIP檔時,看到「檔案已損毀」的訊息?ZIP檔裡,每個檔案都記錄著一個從內容算出的檢查值。開啟的軟體會重新計算同樣的值,如果不一致,就判斷檔案已損毀。這個值就是CRC。

資料是以0和1的排列來傳送與儲存的。在這過程中,0可能翻轉成1,1也可能翻轉成0。原因包括傳進纜線的電氣雜訊、微弱的電波,以及來自宇宙的粒子打到記憶體(軟錯誤)等。

這些都很少發生,但無法降到零。例如錯誤的比例即使只有1兆位元中1個,若每秒傳送10億位元,大約每17分鐘就會錯1個。因此,接收端需要有確認資料的機制。

附上檢查值的概念

商店商品上的條碼(EAN-13,日本稱JAN)通常是13位數字。最後1位,是由其他12位依固定的算法算出的檢查用數字。收銀機做同樣的計算,確認是否和最後1位一致,不一致就重新讀取。

「把從資料算出的簡短值一起送出,由接收端重新計算再比對」。這就是發現錯誤的基本概念。CRC也是同樣的概念,只是計算方法不同。

最簡單的檢查:同位檢查

對0和1的排列來說,最簡單的方法是數1的個數。在最後補上1個0或1,讓資料中1的個數成為偶數。這1個位元稱為同位位元。

例如1011001有4個1(偶數),所以補上0,傳送10110010。途中若只有1個位元翻轉,1的個數會變成奇數,就能發現錯誤。

但如果同時有2個位元翻轉,1的個數仍是偶數,錯誤就會被漏掉。雜訊往往會持續一段時間,相鄰的幾個位元容易一起出錯。這種成塊出現的錯誤,稱為叢發錯誤。出錯的位元若是偶數個,同位檢查就會漏掉。

用加法檢查:檢查碼

也有一種方法,是把資料切成16位元等大小的區塊,全部相加後附上總和。這稱為檢查碼(checksum),網際網路的IP和TCP都有使用(RFC 1071)。

不過,加法即使調換順序,答案也一樣。因此,區塊之間互換位置的錯誤,或某個區塊加1、另一個區塊減1的錯誤,都會被漏掉。CRC則在計算方法上下了工夫,連位元的位置都能區分。

CRC用在哪裡

CRC廣泛用於身邊的通訊和檔案。名稱後面的數字,是檢查值的位元數。

使用的地方CRC的種類保護的對象
有線網路(乙太網路)CRC-32每次傳送的整個單位
Wi-FiCRC-32每次傳送的整個單位
USBCRC-5、CRC-16簡短的指示、資料
SD卡CRC-7、CRC-16命令、資料
PNG圖片CRC-32檔案內的每個區段
ZIP檔CRC-32裡面的每個檔案

乙太網路把資料分成稱為「訊框」的單位來傳送,並在最後附上4位元組(32位元)的CRC。這個部分稱為FCS(訊框檢查序列)。

乙太網路的訊框:最後4位元組放入由前面部分算出的CRC-32(FCS)計算CRC的範圍目的地6來源6類型2資料46~1500FCS4數字為位元組數FCS = 前面部分的CRC-32接收端重新計算並比對
乙太網路一次傳送的單位(訊框)。最後4位元組(FCS)放入從目的地到資料為止的CRC-32。省略的部分:前面的同步用訊號、VLAN欄位。方塊的寬度與位元組數不成比例。

接收的設備會丟棄FCS不一致的訊框。乙太網路本身不會重送,缺少的資料由稱為TCP的機制重送。在Wi-Fi中,正確收到時接收端會回覆,沒有回覆就會重送(「Wi-Fi是怎麼運作的?」)。

原理1:沒有進位、只有0和1的計算

CRC的計算,是在和一般算術稍有不同的「只有0和1的世界」裡進行的。這個世界的加法規則只有以下3條。

  • 0+0=0
  • 0+1=1、1+0=1
  • 1+1=0(沒有進位)

一般的二進位中,1+1=10會進位,但這裡把進位捨去。於是規則變成「兩者不同就是1,相同就是0」,和XOR的規則相同。也就是把加法電路(半加器)的進位輸出拿掉的樣子。

減法也是同樣的規則。0−1是「加上1會變成0的數」,由1+1=0可知是1。也就是說,在這個世界裡,減法和加法都是XOR。每一位都能和相鄰的位無關地計算,所以電路非常簡單。

在數學上,這個只有0和1的世界稱為GF(2)。GF是伽羅瓦體(Galois field)的縮寫,名稱來自19世紀的數學家伽羅瓦。在這篇文章中,只要記得「沒有進位的二進位計算」就夠了。

原理2:把0和1的排列看成多項式

接著,把0和1的排列改寫成稱為多項式的形式。多項式是像x²+3x+1這樣,把x的幾次方相加的式子。CRC把排列的每一位用「x的幾次方」當作名牌,該位是1就寫出來,是0就不寫。

例如1011,從左起依序是x³、x²、x¹、x⁰的位,所以寫成x³+x+1(x⁰寫成1)。這裡不是把數字代入x來計算,x的幾次方只是表示位數位置的記號。

寫成多項式後,就能運用數學上研究已久的多項式性質。因此能夠證明「哪些錯誤一定能發現」。

CRC中當作除數的多項式,稱為生成多項式。乙太網路的CRC-32是x³²+x²⁶+x²³+…+x+1這個32次的式子。規格書省略最高次的x³²,把其餘32位用十六進位寫成04C11DB7。十六進位是把二進位的4位寫成1個字元的方法。

原理3:用手算算看

用小例子來手算CRC。要傳送的資料是4位元的1101,生成多項式是x³+x+1,也就是1011。除數是4位,所以餘數是3位,得到3位元的CRC。

  1. 在資料後面補上和CRC位數相同的3個0,成為1101000(空出放CRC的位置)
  2. 在最左邊的1下方,對齊除數1011的左端寫下,做XOR
  3. 對結果中留在最左邊的1,再對齊1011做XOR。0的位就跳過
  4. 持續到除數超出右端為止。最後留下的右邊3位就是餘數,也就是CRC
CRC的直式計算:把1101000除以1011,重複XOR求出餘數001資料3個01101000被除數1011⊕除數01100001011⊕00111001011⊕00010101011⊕0000001餘數 = CRC傳送 1101 001
⊕是XOR(相同為0,不同為1)。把1011對齊最左邊的1做XOR,逐一消去最左邊的1。淡色的0是已消去的位。最後留下的右邊3位001就是餘數(CRC)。省略的部分:實際規格另外加上的約定(初始值、最後的反轉等)。

這個例子做了4次XOR,得到餘數001。傳送端把這個餘數接在資料後面,傳送1101001。

和一般的直式除法不同,不需要比較「是否比除數大」。最左邊是1就做XOR,是0就前進到下一位。這種單純,正是CRC快速的原因。

接收端把收到的7個位元,直接用同樣的1011去除。沒有錯誤的話,餘數是000。因為附上餘數之後,整體已成為剛好能整除的排列。例如左起第3個位元出錯,收到1111001時,餘數會變成110,就能發現錯誤。

實際的規格會再加上一些約定。例如乙太網路的CRC-32,把計算的初始值全部設為1,最後再把所有位元反轉。初始值設為1,是為了連開頭多出或少了0的錯誤也能發現。

用CRC 計算工具,也能逐段看到這個除法。種類選CRC-8,寬度設3,生成多項式設3,資料格式選十六進位,再輸入0D。0D用二進位表示是00001101,開頭的0不會改變餘數。

原理4:用電路計算

在設備裡,CRC是由專用的小電路,在資料流進來的同時計算的。這種電路把記住1位元的電路串成一串,每來一次節拍訊號(時脈),就把內容往隔壁送1格。這稱為移位暫存器。

如果是3位元的CRC,就排3個記住1位元的方格A、B、C,並在2個地方放入XOR。資料從右邊1位元1位元進入,每次時脈往左前進1格。從左端C溢出的位元,會經由線路送回右邊,進入2個地方的XOR。

計算CRC-3的電路:3個1位元的記憶、2個XOR,以及把左端溢出的位元送回的線路CBA資料把從C溢出的位元送回← 每次時脈往左前進1格記住1位元的電路XOR
除以x³+x+1來求CRC的電路。2個XOR的位置,對應x¹和x⁰的項。資料和3個0都送完後,C、B、A裡留下的就是餘數。省略的部分:時脈的線路、把內容歸零的電路。

只有溢出的位元是1時,2個地方的位元才會反轉。這和直式計算中「最左邊是1就和1011做XOR」是同樣的操作。這種把輸出送回輸入端的接法,稱為線性回饋移位暫存器(LFSR)。依序送入1101和3個0,方格的內容會如下變化。

進入的位元從C溢出的位元之後的內容(C、B、A)
10001
10011
00110
11110
01111
01101
01001

最後留在方格裡的是001,和直式計算的餘數相同。CRC-32只是方格變成32個,XOR的位置也配合生成多項式的項而增加。

CRC一定能發現的錯誤

CRC的強項,在於能說「這種錯誤一定能發現」。只要生成多項式同時有最高次項和x⁰項(+1),以下性質就會成立。這是Peterson和Brown在1961年的論文中證明的性質。

  • 只有1個位元的錯誤,不論發生在哪裡,都一定能發現
  • 範圍不超過CRC位元數的叢發錯誤,不論其中有幾個位元出錯,都一定能發現(CRC-32為32位元以內)
  • 更長的錯誤也幾乎都能發現。假設各種錯誤樣式發生的機會相同,32位元的CRC漏掉的比例約為43億次中1次(2的32次方分之1)

在各種資料長度下,幾個位元以內的錯誤能全部發現,取決於生成多項式的選擇。卡內基美隆大學的Koopman在2002年,調查了所有32位元的生成多項式。乙太網路的CRC-32,在最大長度的訊框中,能發現3個位元以內的所有錯誤。不過他也發現,還有更強的多項式。

反過來說,CRC會漏掉的,是錯誤樣式(哪些位元出錯)能被生成多項式整除的情況。以剛才的1101001為例,若左起第1、3、4個位元一起出錯,錯誤樣式就是1011000。它能被1011整除,所以餘數仍是000,無法察覺。這是跨越4個位元的錯誤,超出了3位元CRC的保證範圍。實際上會使用16位元或32位元的CRC。

CRC做不到的事

無法更正錯誤

CRC能知道錯誤「存在」,但通常無法告訴你錯誤在「哪裡」。發現錯誤之後,只能丟掉資料請對方重送,或通知資料已損毀。

要更正錯誤,就得增加檢查用的位元,設計成連哪個位元出錯都能知道。這稱為錯誤更正碼(ECC)。漢明在1950年發表的漢明碼,在4位元資料上加3位元,能更正1個位元的錯誤。伺服器用的ECC記憶體,每64位元加上8位元,能更正1位元的錯誤,並發現2位元的錯誤。

能更正更多錯誤的編碼,有里德和所羅門在1960年發表的里德-所羅門碼。它用於CD和QR碼,QR碼即使有一部分弄髒也能讀取,就是這個緣故。它和CRC一樣,使用多項式的計算。

能更正錯誤的編碼,檢查用的位元較多,計算也較重。在可以重送的通訊中,用輕量的CRC發現錯誤再重送,往往比較有效率。在無法重送的廣播、與太空之間的通訊等,則使用能更正錯誤的編碼。這稱為前向錯誤更正(FEC)。

無法識破蓄意的竄改

CRC的計算方法公開在規格中,也不使用祕密金鑰。竄改的人只要用新的資料重新算出CRC並換上即可。CRC發現的是偶然的錯誤,而不是惡意的竄改。

實際上,早期無線區域網路的加密方式WEP,曾用CRC-32來確認內容。2001年,Borisov等人證明,可以不解開加密就竄改內容,還能讓CRC也對得上。因為WEP的加密和CRC都只用XOR計算,所以能算出反轉哪些位元,會讓CRC的哪裡改變。

要發現竄改,要使用以祕密金鑰計算的訊息鑑別碼或數位簽章(「加密是什麼?」)。密碼學使用的雜湊函數,也設計成實際上無法做出相同值的另一份資料。而CRC卻能輕易做出這樣的資料。

同位檢查、檢查碼、CRC、ECC的差異

方法能發現的錯誤能否更正使用場合的例子
同位檢查奇數個位元的錯誤無法更正序列通訊(UART)
檢查碼多數的錯誤(會漏掉互換等)無法更正IP、TCP
CRC1位元錯誤和短的叢發錯誤一定能發現,其他也幾乎都能通常不更正(重送)乙太網路、Wi-Fi、USB、檔案
ECC(錯誤更正碼)一定數量以內的錯誤能更正ECC記憶體、SSD、QR碼、CD

常見的誤解

誤解:有了CRC,損毀的資料會自動修好

實際上,CRC只負責到發現錯誤為止。通訊中看起來像是修好了,是因為請對方重送了丟掉的資料。如果只有1個位元出錯,有時能從餘數的值推算出位置。名為ATM的通訊方式,就是這樣更正簡短標頭中的1位元錯誤。但2個位元以上的錯誤,可能被誤認為1位元的錯誤,所以通常只用來發現錯誤。

誤解:CRC對得上,就證明沒有被任何人竄改

實際上,竄改的人只要換上新的CRC,CRC就會對得上。能知道的只有「混入偶然錯誤的可能性很低」。要發現竄改,需要使用金鑰的訊息鑑別碼或數位簽章。因為名稱裡有「檢查」二字,看起來就像是安全的保證。

誤解:CRC越長,任何錯誤都能發現

實際上,不論CRC多長,都會漏掉能被生成多項式整除的錯誤。若是隨機的錯誤,32位元的CRC約43億次會漏掉1次。此外,CRC保護的只有從附上到檢查之間的區間。在附上CRC之前,就已在設備內損毀的資料,會被當成正確的資料通過。

從數字來看

數字代表什麼
4位元組(32位元)乙太網路訊框最後附上的CRC(FCS)的大小
約43億次中1次32位元的CRC漏掉隨機錯誤的大約比例
約每17分鐘1個在1兆位元錯1個的傳輸路徑上,每秒傳送10億位元時的錯誤間隔

進一步學習

接著閱讀

系列「技術背後的基礎(物理・化學・數學)」的文章

  1. 阿瑞尼斯方程式是什麼?溫度讓反應和故障快幾倍
  2. 矩陣乘法要算幾次?AI晶片的運算量與運算強度
  3. 費米分布和波茲曼分布是什麼?半導體電子的算法
  4. 穿隧效應是什麼?電子穿過薄牆的原理與晶片中的影響
  5. 擴散是什麼?雜質在矽中擴散的原理與√(Dt)的意義
  6. CRC是什麼?用0與1的除法找出傳輸錯誤的原理
  7. 時間常數RC是什麼?決定導線延遲與時脈速度的原理
  8. 分貝(dB)是什麼?把乘法變成加法的單位與dBm
  9. 電容器是什麼?把電儲存起來的原理與用途
  10. 交流電和直流電有什麼不同?簡單認識阻抗
  11. 運算放大器是什麼?把微小訊號準確放大的原理
  12. 電阻是什麼?簡單看懂歐姆定律與電壓、電流

這個領域的題目: 資訊理論與編碼基礎

參考資料

入門解說一覽