編寫程序實現IEEE 802.3以太網幀封裝。
要求畫出界面,以太網幀的數據部分、源MAC地址和目的MAC地址均從界面輸入;
計算後的校驗和字段和封裝後的結果可以從界面上輸出;
生成多項式G(X)=X8+X2+X+1;
使用的操作系統、語言和編譯環境不限,但必須在報告中註明。
能夠實現CRC計算過程的可視化;
能夠從界面上控製程序的運行。
按802.3標準的幀結構如下表所示(802.3標準的Ethernet幀結構由7部分組成)
802.3標準的幀結構
| 前導碼 | 幀前定界符 | 目的地址 | 源地址 | 長度字段 | 數據字段 | 校驗字段 |
|---|---|---|---|---|---|---|
| 7B | 1B | (6B) | (6B) | (2B) | (長度可變) | (4B) |
其中,幀數據字段的最小長度為46B。如果幀的LLC數據少於46B,則應將數據字段填充至46B。填充字符是任意的,不計入長度字段值中。
在校驗字段中,使用的是CRC校驗。校驗的範圍包括目的地址字段、源地址字段、長度字段、LLC數據字段。
使用可視化的界面,接收用戶輸入的目的地址、源地址、長度字段、數據字段。並且支持生成隨機數據,這樣可以減少用戶輸入
利用生成多項式,計算待校驗數據的校驗字段。其中待校驗字段為整數個字節,生成多項式的階不超過32,計算出的餘數為4個字節
模仿Windows 10計算器的bit輸入鍵盤,讓用戶可以通過點擊鼠標即可輸入生成多項式等數據
將計算FCS後的幀發生給接收者,接收者可以校驗是否出錯。可以模擬出錯,比如手動修改數據,然後再校驗是否出錯。
使用較短的二進制數據,動態顯示CRC的計算過程,並支持校驗功能。可以自定義每一步的延遲時間來控制顯示速度,並可以隨時停止演示。
根據以下公式
可以得到
即,將一個數擴大n倍,然後再加上餘數,此時$$mod m$$ 的餘數不變

private byte [ ] CalcCRC ( string v )
{
var data = new Queue < char > ( v . ToArray ( ) ) ; // 被除数
char [ ] divisor = binaryString . ToArray ( ) ; // 除数
Queue < char > S = new Queue < char > ( ) ; // 商
int width = divisor . Length ; // 每次取 width 个字符进行异或运算
Queue < char > str = new Queue < char > ( ) ; // 每次取的长度为 width 的部分被除数
// 获取前 width - 1 个字符,填入到str中
for ( int i = 0 ; i < width - 1 ; i ++ )
{
str . Enqueue ( data . Dequeue ( ) ) ;
}
while ( data . Count != 0 )
{
str . Enqueue ( data . Dequeue ( ) ) ;
if ( str . First ( ) == '0' )
{
S . Enqueue ( '0' ) ;
str . Dequeue ( ) ;
}
else
{
S . Enqueue ( '1' ) ;
var temp = str . ToArray ( ) ;
str . Clear ( ) ;
for ( int i = 1 ; i < temp . Length ; i ++ )
{
str . Enqueue ( temp [ i ] == divisor [ i ] ? '0' : '1' ) ;
}
}
}
// 计算已经结束,str中的值就是结果,下面的代码可以不用看了
// 将str中的值转成4个字节的二进制数组
var res = new string ( str . ToArray ( ) ) . PadLeft ( 32 , '0' ) ;
var result = new byte [ 4 ] ;
// 将字符串格式化为byte
for ( int i = 0 ; i < 4 ; i ++ )
{
result [ i ] = Convert . ToByte ( res . Substring ( i * 8 , 8 ) , 2 ) ;
}
return result ;
}待處理數據:1010 0111 0110 0
生成多項式:1010 1101 0 (
將待處理數據全部放入隊列data中
data = [1010011101100]
生成多項式共9位,所以先讓隊列data的前8項出隊,並將數據放入隊列str中
str = [10100111]
data = [01100]
隊列data.Count = 5 != 0,繼續執行
將隊列data的第項出隊,並放入隊列str中
str = [101001110]
data = [1100]
str的第一個元素是1
向列S中插入1
將隊列str的值和生成多項式的值進行按位異或,並將結果的後8個字符複製給str 101001110 ^ 101011010 = 000010100
S = [1]
str = [00010100]
data = [1100]
隊列data.Count = 4 != 0,繼續執行
將隊列data的第一項出隊,並放入隊列str中
S = [1]
str = [000101001]
data = [100]
str的第一個元素是0
向列S中插入0 ,並讓str的第一項出隊
S = [10]
str = [00101001]
data = [100]
隊列data.Count = 3 != 0,繼續執行
將隊列data的第一項出隊,並放入隊列str中
S = [10]
str = [001010011]
data = [00]
str的第一個元素是0
向列S中插入0 ,並讓str的第一項出隊
S = [100]
str = [01010011]
data = [00]
隊列data.Count = 2 != 0,繼續執行
將隊列data的第一項出隊,並放入隊列str中
S = [100]
str = [010100110]
data = [0]
str的第一個元素是0
向列S中插入0 ,並讓str的第一項出隊
S = [1000]
str = [10100110]
data = [0]
隊列data.Count = 1 != 0,繼續執行
將隊列data的第項出隊,並放入隊列str中
S = [1000]
str = [101001100]
data = []
str的第一個元素是1
向列S中插入1
將隊列str的值和生成多項式的值進行按位異或,並將結果的後8個字符複製給str 101001100 ^ 101011010 = 000010110
S = [10001]
str = [00010110]
data = []
隊列data.Count = 0 == 0,結束,餘數為str = 00010110 ,商為S = 10001
整個計算過程為:







