编写一个计算机程序用来计算一个文件的16位校验和
题目
编写一个计算机程序用来计算一个文件的16位校验和。最快速的方法是用一个32位的整数来存放这个和。记住要处理进位(例如,超过16位的那些位),把它们加到校验和中。*
原理:
把要发送的数据看成16比特的二进制整数序列,并计算他们的和。若数据字节长度为奇数,则在数据尾部补一个字节的0以凑成偶数。
例子:
16位校验和计算,下图表明一个小的字符串的16位效验和的计算。
为了计算校验和,发送计算机把每对字符当成16位整数处理并计算校验和。如果效验和大于16位,那么把进位一起加到最后的校验和中。
程序流程图
参考代码
package bridge;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CCR16_check_sum {
public static void main(String[] args) throws IOException {
checkSum();
}
public static String checkSum() throws IOException {
String result = new String();
File file=new File("infile.txt"); //创建新文件infile
if(!file.exists()) {
file.createNewFile();
FileWriter fw = new FileWriter(file,true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write("Hello world."); //新文件写入信息
bw.flush();
bw.close();
fw.close();
}
FileReader fr=new FileReader(file);
BufferedReader br=new BufferedReader(fr);
String str=br.readLine(); //读取文件的信息
System.out.println("读取文件的内容为:"+str);
byte[] buff = str.getBytes(); //byte数组获取每个字节的Ascill值
int byteNum=buff.length; //文本含有的字节数
String choose=(byteNum%2==0? "偶数":"奇数"); //判断字节数是奇数还是偶数
System.out.println("文本含有的字节长度为:"+choose);
int num = 0;
if(choose.equals("偶数")) {
num = (int) Math.ceil(buff.length/2);
for(int i=0; i<buff.length; i++) {
String hex = Integer.toHexString(buff[i] & 0xFF);
if(hex.length() == 1) {
hex = "0" + hex ;
}
result += hex.toUpperCase();
}
}
if(choose.equals("奇数")) {
num = (int) Math.ceil(buff.length/2)+1;
for(int i=0; i<buff.length; i++) {
String hex = Integer.toHexString(buff[i] & 0xFF);
if(hex.length() == 1) {
hex = "0" + hex ;
}
result += hex.toUpperCase();
}
result +="00";
}
System.out.print("所读文件每对字符所对应的十六进制的整数序列为:");
int[] ten = new int[100];
String[] b = new String[100];
for(int i=0; i<num; i++) {
b[i] = result.substring(i*4, i*4+4);
System.out.print("0x"+b[i]+" ");
}
int notnulllength = 0;
for(int i = 0; i<b.length; i++) { //获取加法项的非空项数
if(b[i] != null) {
notnulllength++;
}
}
System.out.println('\t');
for( int i = 0; i< notnulllength;i++)
{
ten[i]=Integer.parseInt(b[i],16); //将非空加法项转化为10进制的数
}
int sum = 0;//计算和的十进制
int carry = 0;//进位数
String checkSum = null;//十六进制的校验和
for(int i=0; i<notnulllength; i++) {
//将非空加法项转化为10进制的数
//ten[num+1]=0;
sum += ten[i];
//System.out.println(sum);
checkSum = Long.toHexString(sum);
//System.out.println(checkSum);
int judge = Integer.parseInt(checkSum,16); //将校验和转化为10进制的判断数
if(judge>65535) { //从第一个加法项每次累加为一个判断数,看这个判断数的十六进制的值是否大于FFFF
carry = 1; //进位数置1
sum=judge-65536+carry; //总和=原来的判断数减去十六进制数10000再加上进位1
}
}
System.out.println("以上数据的16位效验和为:0x"+checkSum);
return null;
}
}
运行结果