基於計網作業---求文件校驗和--基於java和python版本的實現

編寫一個計算機程序用來計算一個文件的16位效驗和。最快速的方法是用一個32位的整數來存放這個和。記住要處理進位(例如,超過16位的那些位),把它們加到效驗和中。
要求:1)以命令行形式運行:check_sum infile
其中check_sum爲程序名,infile爲輸入數據文件名。
2)輸出:數據文件的效驗和
附:效驗和(checksum)
參見RFC1071 - Computing the Internet checksum
原理:把要發送的數據看成16比特的二進制整數序列,並計算他們的和。若數據字節長度爲奇數,則在數據尾部補一個字節的0以湊成偶數。
例子:16位效驗和計算,下圖表明一個小的字符串的16位效驗和的計算。
爲了計算效驗和,發送計算機把每對字符當成16位整數處理並計算效驗和。如果效驗和大於16位,那麼把進位一起加到最後的效驗和中。

在這裏插入圖片描述
目的:體驗多種語言不同效果
c++的2個版本

版本三:python版本check_sum.py

命令行輸入:python check_sum.py filePath

import sys  # 爲了讀取命令行的信息
import os.path  # 判斷是否存在文件

CONST_VALUE = int('0x10000', 16)


def calculate(filePath):
    if not os.path.isfile(filePath):
        print("該地址不存在")
    else:
        try:
            infile = open(filePath, 'rb')
        except IOError:
            print("Something wrong about File " + filePath + "happens..Try again.")
        time = 0
        print('文本中讀取的內容如下:')
        all_num_lst = ""
        for i in infile.read():
            print(chr(i), ":", hex(i), end="  ")
            time += 1
            temp_str = str(hex(i)).replace("0x","")
            if len(temp_str) == 1:  # ascill碼小於16時
                temp_str = '0' + temp_str
            if time % 2 == 1 and time > 1:  # 把整數轉換成int類型後再轉字符類型去掉0x標誌
                all_num_lst = all_num_lst + "-" + temp_str  # 加上-符號區分2個16字節組合
            else:
                all_num_lst = all_num_lst + temp_str
            if time % 5 == 0:  # 控制每行5個數據
                print('\n')
        print("十六位校驗:", all_num_lst)
        if time % 2 == 1:
            print("數據字節長度爲奇數,數據尾部補一個字節的0以湊成偶數")
            all_num_lst = all_num_lst + "00"  # 補00字符
        else:
            print("數據字節長度爲偶數")
        print("十六位校驗:", all_num_lst)
        all_num_lst = "0x" + all_num_lst
        all_num_lst = all_num_lst.replace("-", "-0x")
        sum = 0
        for n in all_num_lst.split('-'):
            sum = sum + int(n, 16)
        carry = int(sum / CONST_VALUE)  # 求值後爲int類型,對0x10000求,表示爲進位
        result = int(sum % CONST_VALUE) + carry  #
        print("校驗和爲:", hex(result))
        infile.close()


def main():
    # filePath = sys.argv[1].strip()  # 因爲在命令行使用python文件的時候是 python check_sum.py filePath,sys.argvshi從python後開始的元素
    filePath = r"C:\Users\Lenovo\Desktop\1.txt"   # 測試時使用的地址
    calculate(filePath)


if __name__ == "__main__":
    main()

在這裏插入圖片描述
在這裏插入圖片描述

版本四:java版本

javac check_sum.java
java check_sum filePath
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class check_sum {
    public static void main(String infile1[]) throws IOException {
        String[] infile=new String[1];
        infile[0]="C:\\Users\\Lenovo\\Desktop\\1.txt";//需要用命令行的時候這裏刪掉
        // TODO Auto-generated method stub
        InputStream inputStream=null;//輸入流
        int data;//讀取到的一個字節
        int sum=0;//計算十六進制的個數
        final int Ox10000=Integer.parseInt("10000",16);//十六進制10000對應的十進制數值

        StringBuffer buffer=new StringBuffer();
        inputStream=new FileInputStream(infile[0]);//打開文件

        System.out.println("文本中讀取的內容如下:");

        while((data=inputStream.read())!=-1){
            sum++;
            if(sum%2==1&& sum >1)
                buffer.append("-");
            String hex=Integer.toHexString(data);//十進制轉十六進制
            System.out.print((char)data+":Ox"+hex+"\t");//輸出
            if(sum%5==0)
                System.out.println();//每行輸出五個
            if(hex.length()==2)
                buffer.append(hex);
                //若字節的ASCII小於16,則填充0
            else{
                buffer.append("0");
                buffer.append(hex);
            }
        }
        System.out.println("\n"+buffer.toString());
        //若數據字節長度爲奇數,則在數據尾部補一個字節的0以湊成偶數。
        if(sum%2==1){
            System.out.println("\r數據字節長度爲奇數,數據尾部補一個字節的0以湊成偶數");
            buffer.append("00");
        }else{
            System.out.println("\r數據字節長度爲偶數");
        }
        System.out.println(buffer.toString());
        String segments[]=new String(buffer).split("-");//得到多個十六進制的數值
        System.out.println("十六位的數值如下:");
        for(String segment:segments)
            System.out.print(segment+"\t");
        System.out.println();
        int decimal;
        int result=0;//保存相加後的結果

        for(String segment:segments){
            decimal=Integer.parseInt(segment,16);
            result+=decimal;//累加
        }
        
        int carry=result/Ox10000;//進位位

        String hex=Integer.toHexString(result%Ox10000+carry);

        System.out.println("\r校驗和爲:Ox"+hex);

        inputStream.close();//關閉文件
    }
}

在這裏插入圖片描述

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章