基于计网作业---求文件校验和--基于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();//关闭文件
    }
}

在这里插入图片描述

在这里插入图片描述

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