ByteScope

CRC Calculator

一份輸入、113 種公開 CRC,外加一個能指名你的裝置在用哪一種的搜尋。

位元組不會離開你的瀏覽器,每一個檢查碼都在本機算完。

輸入

9 位元組開頭幾個位元組:31 32 33 34 35 36 37 38 39

自訂參數

Rocksoft 模型的六個數字。任何一份講 CRC 的規格書,講的就是這六個,順序通常也一樣——而且常常沒給演算法名字。

結果

—

對「123456789」的 check

—

每一份公開的 CRC 都會寫這個值。它跟規格書上的 check 對得起來,上面那六個數字才真的是那份文件講的演算法——先確認這個,再去信左邊的結果。

所有具名的 CRC

一份輸入,113 種公開演算法,一次全算。哪一列的結果跟你手上的檢查碼一樣,那就是你要找的演算法。

0 種

沒有演算法符合這個條件。

從檢查碼反推演算法

手上有一個訊框和它帶的檢查碼,但沒人寫下那是哪一種 CRC。把訊框放上面的輸入、檢查碼放這裡,讓搜尋回答你。

裝置或檔案針對上面那串位元組,實際帶著的值。

符合:0

113 個公開模型之後,搜尋會把 8 位元的多項式全試一遍,再試 16 位元;init 與 xorout 各取全 0 或全 1,兩種反轉設定都試。16 位元以上不做窮舉:四十億個多項式不是一個瀏覽器分頁跑得完的搜尋。

非 CRC 的檢查碼

結尾那幾個位元組不一定是 CRC。世上另外一半的協定實際在用的就是這八種,它們算的是同一份輸入。

檢查碼十六進位十進位
sum8位元組加總,取 8 位元。——
sum16位元組加總,取 16 位元。——
xor8所有位元組 XOR 起來——Modbus ASCII 和 NMEA 的 LRC。——
fletcher16兩條 mod 255 的累加,所以順序換掉答案就會變。——
fletcher32同一套想法搬到 16 位元小端序字組,mod 65535。——
adler32Fletcher 的近親,mod 65521——每個 zlib 串流結尾都是它。——
internetChecksumRFC 1071:把 16 位元大端序字組的一補數和再取一次一補數。IP、UDP、TCP 的標頭都用它。——
bsdChecksum先右旋一位再相加——BSD 的 sum(1) 印出來的就是這個。——

NMEA 0183 語句

檢查碼—

把開頭的 $ 或 ! 到 * 之間的字元全部 XOR。只有這一個吃的是整句話而不是上面那串位元組,因為標準就是這樣定的。

關於這個工具

訊框結尾那兩個位元組

協定側錄的結尾是 4b 37,而拿到的文件上只寫著「CRC-16」。那不是演算法名字,那是一個家族的名字:公開的 16 位元 CRC 有好幾十種,差別在多項式、起始值、位元順序和最後那道 XOR,挑錯了會得到一個錯的答案,而且完全不會有任何跡象告訴你錯了。所以這頁不要求你先選。把訊框貼進來——文字、十六進位傾印或整個檔案都行——它會一次把 CRC-3/GSM 到 CRC-82/DARC 共 113 種公開演算法全部算出來。哪一列的結果等於你手上那幾個位元組,答案就出來了,連名字一起。

決定一個 CRC 的六個數字

規格書真的把 CRC 寫清楚的時候,寫的就是 Rocksoft 模型:width、poly、init、refin、refout、xorout。把它們填進去,結果馬上出現,旁邊還會多出一個比外表重要得多的數字——check 值,也就是這組參數對 123456789 這九個字元自己算出來的結果。每一份公開的 CRC 都會寫這個值,像樣的規格書也都會寫。這頁的 check 跟你文件上的 check 對得起來,你填的那六個數字才真的是那份文件講的演算法,左邊的結果也才在那一刻起值得信。計算機跟猜的差別就在這裡。

反過來找演算法

當每個名字都對不上、規格書也根本不存在,就把訊框和它帶的檢查碼交給搜尋。它會先跑完所有公開模型,接著窮舉每一個 8 位元多項式、每一個 16 位元多項式,init 和 xorout 各取全 0 或全 1,兩種反轉設定都試。任何被回報出來的結果,都一定滿足你給的樣本:它可能漏掉答案,但絕不會捏造一個。邊界寫在明處,不藏起來——16 位元以上不做窮舉,因為四十億個多項式不是一個瀏覽器分頁跑得完的搜尋;超過 64 KB 的樣本則直接拒收,因為光是目錄那一輪,就會讓 113 個逐位元的引擎先把整份樣本啃過一遍。反查是為一則訊息設計的,不是為一整包韌體。

封包結尾不一定是 CRC

很多協定的結尾是更簡單的東西,而「那根本不是 CRC」本身就是一個有用的答案。同一份輸入也會跑過八種非 CRC 的檢查碼:sum8、sum16、xor8、fletcher16、fletcher32、adler32、RFC 1071 的 internet checksum,以及 BSD sum(1) 那種先右旋再相加的做法。另外還有一個 NMEA 0183 欄位,它吃的是整句語句而不是位元組,因為標準就是這樣定的。全部都在這一頁裡的 Web Worker 跑:不上傳、不用帳號,也不必跟任何人解釋你當時在逆向哪一份韌體。

常見問題

「CRC-32」到底是哪一個?

通常是 CRC-32/ISO-HDLC,也就是 zip、gzip、PNG 和乙太網路用的那個。不過這個名字同時也以 CRC-32 和 CRC-32/ADCCP 公開過;而寫著 CRC-32C 的檔案指的是 CRC-32/ISCSI,那是完全不同的多項式。表格會把每個別名列在正式的 reveng 名稱旁邊,所以你可以用文件上的叫法去搜,落到它真正指的那個模型。

算出來跟我的裝置對不起來,通常是哪裡錯了?

幾乎不會是多項式,而是位元組範圍:檢查碼很可能還蓋到終端機沒顯示的標頭,或是長度欄位也被算進去,又或者它比你以為的早一個位元組結束。第二常見的是反轉,refin 和 refout 正是 CRC-16/ARC 和 CRC-16/XMODEM 的分野。拿你認為被涵蓋的那串位元組去跑反查;如果什麼都找不到,該換的是位元組,不是演算法。

check 值是幹嘛的,為什麼一直出現?

它是該演算法對 123456789 這九個 ASCII 字元算出來的值,也是唯一一個能讓你不必信任這頁就驗證參數的數字。每一份公開的 CRC 都會寫。填好參數,把這裡顯示的 check 跟規格書上印的 check 比一比,你就在還沒用到自己任何一個位元組之前,確認了兩份文件講的是同一個演算法。

為什麼反查不肯收我整份韌體檔?

因為它第一件事就是把 113 個公開模型全部套在整份樣本上跑一遍,而且這發生在任何預算或中止機制生效之前;引擎又刻意是逐位元的,這樣連 CRC-82/DARC 這種寬度都算得準。64 KB 時這一輪大約兩秒,1 MB 時要半分鐘,看起來就跟分頁當掉一模一樣。上限是 64 KB,而且拒絕發生在搜尋開始之前。對大檔案算 CRC 本身沒問題——那是上面那張表,而且一次只跑一種演算法。

CRC 足以偵測有人動過手腳嗎?

不行,它本來也不是為此設計的。CRC 抓的是意外的損壞——線路上被翻掉的一個位元、快閃記憶體上的壞塊——而且抓得非常好。但它是線性的,能改你資料的人也能重算結尾那幾個位元組,或反推出要補哪些位元才能讓值回到原樣。如果威脅來自人而不是一條有雜訊的線,你要的是密碼學雜湊;若整個檔案有可能被換掉,要的是 MAC。