2020.12.17
本文章属于转载型文章,
文章的思路来自:
参考文章
要求
编写一个计算机程序用来计算一个文件的 16 位效验和。最快速的方法是用一个 32 位的整数来存放这个和。记住要处理进位(例如,超过 16 位的那些位),把它们加到效验和中。
1)以命令行形式运行:check_sum infile其中 check_sum 为程序名,infile 为输入数据文件名。
2)输出:数据文件的效验和
例子
程序逻辑图
Txt文件内容
程序运行结果
计算过程
代码
import java.io.FileInputStream;
import java.io.IOException;
public class check_sum {
public static void main(String[] args) {
try{
if(args == null || args.length != 1){
System.out.println("使用方式:java class名 文件路径");
}else{
System.out.println("开始进行校验");
System.out.println("校验和为"+calculate(args[0]));
}
}catch (IOException e){
e.printStackTrace();
System.out.println("出现了IO异常,请检查");
}
}
public static String calculate(String fileName) throws IOException{
//使用字节流来进行读取文件
FileInputStream fis = new FileInputStream(fileName);
byte[] curBytes = new byte[2];
int n;
//用整数来存储结果
int sum = 0;
//如果读到文件结尾,返回-1
while((n = fis.read(curBytes)) != -1){
if(n == 1){
//是奇数个字节
sum += (curBytes[0] << 8);
}else{
//是偶数个字节
sum += (curBytes[0] << 8);
sum += curBytes[1];
}
}
fis.close();
//大于16位
if(sum > 0xffff){
sum = (sum/65536) + (sum%65536);
}
//取反得到校验和
return Integer.toHexString(~sum).substring(4);
}
}
总结
1、虽然例子图中是两个16进制的数值进行合并,实际上在代码中是使用两个8位二进制数合并为一个16位的数值,在计算出结果后再进行16进制的转换。
2、值得注意的是,~sum的值是ffff8e03,因此子串要从第四位开始显示校验码,因为int是一个32位的数值,没有取反之前,sum的值为000071FC,在java中前缀0不予显示,因此是71FC。
3、代码中使用了字节流而不是字符流,使用字符流进行读取文件非常容易出错,而字节流是最好的选择,写出来的代码也非常的整洁。