2011-08-17 09:20:08Morris

c102. Software CRC

c102. Software CRC

內容 :

你在一家有很多個人電腦的公司上班。你的老闆,連一分都省博士,想要把這些個人電腦連線,但是他又不想要花錢買網路卡。由於你不小心告訴老闆每台電 腦出廠時就有一個非同步串列埠在上面,老闆當然把腦筋動到這不用花錢的解決方案上。於是可憐的你被指派來完成這工作軟體的需求,以使這些電腦之間可以連 線。

你已經讀了許多關於通訊的書並且知道在傳送及接收訊息時,確保訊息的正確性是一個重點。典型的作法是在訊息的最後加上額外的錯誤檢查碼。這個資訊允 許接收程式檢查出傳送的資訊是否有錯誤(在大多數的例子)。於是,你跑到圖書館借回了一本關於通訊厚厚的書,利用週末(當然沒有加班費)研究錯誤檢查的部 分。

最後,你決定CRC(cyclic redundancy check)是最適合的錯誤檢查方式。以下描述這個機制:

CRC Generation

待傳遞的訊息被視為一列長長二元數。訊息的第一個位元組(byte)被當作這二元數最重要的位元組,第二個位元組被當作第二重要的位元組,依此類推。這個二元數被稱為"m"。當傳送時會在"m"之後加上2個位元組的CRC檢查碼,然後整個二元數稱為"m2"。

這個CRC的檢查碼被產生使得"m2"可以整除某個16位元的值 "g"。所以當接收端收到一訊息,只要把他除以 "g",如果餘數為0即代表此訊息正確。

你也注意到,大部分建議採用的g值都是奇數,所以你決定用 34943 當作 g 的值。現在你迫切的任務就是對待傳送的訊息,寫一個程式算出這個CRC的值。

例如:若要傳送的訊息為:AB(二進位的表示式為:01000001 01000010),你必須算出的CRC值應為60 1B(01100000 00011011的十六進位表示式),使得 01000001 01000010 01100000 00011011可以整除34943(10進位)。

輸入說明 :

每組測試資料一列,含有一個待傳送的訊息(不會超過1024個ASCII字元的長度),列結束字元(End of line)不被視為待傳送訊息的一部份。若遇到只含 # 的一列,代表輸入結束(此列無須輸出)。請參考Sample Input。

輸出說明 :

對每組測試資料輸出一列,CRC的值(以十六進位表示)。請注意:CRC的值一定介於0到34942(十進位)之間。輸出格式請參考Sample Output。

範例輸入 :

this is a testAABNothing gonna change my love for you.#

範例輸出 :

77 FD00 000C 8660 1B57 98

提示 :

* Luck 貓翻譯

出處 :

ACM 128



作法 : 大數mod小數
256 進制數 去 mod 34943,

#include<stdio.h>
main() {
    char s[1030], *A;
    while(gets(s)) {
        if(s[0] == '#')    break;
        int CRC = 0;
        for(A = s; *A; A++)
            CRC = ((CRC*256)+(*A))%34943;
        CRC = ((34943 - ((CRC*256)%34943*256))%34943 + 34943)%34943;
        printf("%02X %02X\n", CRC/256, CRC%256);
    }
    return 0;
}