基于计网作业---求文件校验和--带c++进制转换功能实现

编写一个计算机程序用来计算一个文件的16位效验和。最快速的方法是用一个32位的整数来存放这个和。记住要处理进位(例如,超过16位的那些位),把它们加到效验和中。
要求:1)以命令行形式运行:check_sum infile
其中check_sum为程序名,infile为输入数据文件名。
2)输出:数据文件的效验和
附:效验和(checksum)
参见RFC1071 - Computing the Internet checksum
原理:把要发送的数据看成16比特的二进制整数序列,并计算他们的和。若数据字节长度为奇数,则在数据尾部补一个字节的0以凑成偶数。
例子:16位效验和计算,下图表明一个小的字符串的16位效验和的计算。
为了计算效验和,发送计算机把每对字符当成16位整数处理并计算效验和。如果效验和大于16位,那么把进位一起加到最后的效验和中。

在这里插入图片描述
java和python2个版本

版本一:没有考虑出现中文格式的解决方法

#include<iostream>
#include<fstream>
#include<vector>
#define MAXVALE "0x10000"
using namespace std;

int charToInt(char c) {
	int temp = (int)c;
	if (temp >= (int)'0' && temp <= (int)'9') {
		return (c - '0');
	}
	else if (temp >= (int)'A' && temp <= (int)'F') {
		return (c - 'A') + 10;
	}
}
char intToChar(int i) {
	if (i >= 0 && i <= 9) return i + '0';
	else if (i < 16)	 return (i - 10) + 'A';

}
int  hexToInt(string hex) {
	 //例如0x1234	
	string temp = hex.substr(2, hex.length() - 2);
	int result = 0;
	for (int i = 0; i < temp.length(); i++) {
		result *= 16;
		result += charToInt(temp[i]);
	}	
	return result;
}
string intToHex(int integer) {
	string result = "";	
	while (integer > 0) {
		result = intToChar(integer % 16) + result;
		integer /= 16;
	}		
	return "0x" + result;
}
void readFromText(string filePath);
void checksums(vector<string> vec) {
	int data_sum = 0;
	string temp = "";
	for (int i = 0; i < vec.size(); i++) {
		if (i % 2 == 0) {
			temp = "0x"+vec[i];
		}
		else {
			temp += vec[i];
			data_sum += hexToInt(temp);
		}
	}	
	int maxValue = hexToInt(MAXVALE);
	int carry = data_sum / maxValue;
	int result = carry + data_sum % maxValue;
	cout <<"\n校验码为"<<intToHex(result) << endl;
}
int main(int args,char**argv) {
	/*string filePath;
	if (args > 1) {
		filePath = argv[1];
	}
	else {
		cout << "请输入正确的格式:xx.exe filePath" << endl;
	}*/
	string filePath = "C:\\Users\\Lenovo\\Desktop\\1.txt";
	readFromText(filePath);


}
void readFromText(string filePath) {
	ifstream infile(filePath, ios::in);
	if (!infile){
		cerr << "File couldn't be open" << endl;
	}
	vector<string>vec;
	char ch;
	int time = 0;
	while (infile.get(ch)) {
		if (time % 5 == 0)
			cout << endl;
		time += 1;
		cout << ch << " : ";
		string hexNum = intToHex((int)ch);
		cout << hexNum << "\t";
		if (hexNum.length() == 1)//为1或2
			hexNum = "0"+hexNum.substr(2,hexNum.length()-2);
		else
			hexNum =hexNum.substr(2, hexNum.length() - 2);
		vec.push_back( hexNum );
	}
	if (vec.size() % 2 == 1) {
		vec.push_back("00");
	}
	infile.close();
	cout << endl;
	checksums(vec);
}


在这里插入图片描述

版本二:可以使用中文

考虑用二进制补码来转换

#include<iostream>
#include<fstream>
#include<vector>
#define MAXVALE "0x10000"
using namespace std;

int charToInt(char c) {
	int temp = (int)c;
	if (temp >= (int)'0' && temp <=(int)'9') {
		return (c - '0');
	}
	else if (temp >= (int)'A' && temp <= (int)'F') {
		return (c - 'A') + 10;
	}
}

char intToChar(int i) {
	if (i >= 0 && i <= 9) return i + '0';
	else if (i < 16)	 return (i - 10) + 'A';

}

string intToBin(int integer) {//求的是补码
	string result = "";
	int sign = 0;
	if (integer < 0)
	{
		sign = 1;
		integer *= -1;
	}
	while (integer > 0) {
		result = intToChar(integer%2)+result;
		integer >>= 1;
	}
	while ((result.size() % 8!=0 && result.size()>0)||result.size()==0)
		result = '0' + result;
	//从右往左数,第一个1左边的数取反 
	string temp="";
	if (sign==1 && integer< 128) {
		for (int i = 7; i >= 0; i--) {	//从右往左数
			if (result[i] == '1') {		//找到第一个1
				temp = result[i] + temp;
				for (int j = i-1; j >=0; j--) {//左边所有数
					if (result[j] == '0')
						temp = '1' + temp;
					else
						temp = '0' + temp;
				}
				break;
			}
			else
				temp = result[i] + temp;
		}
		result = temp;
	}	
	result = "0B" + result;
	return result;
}

int binToInt(string bin) {
	int result=0;
	bin = bin.substr(2, bin.length() - 2);	
	while ((bin.size() % 8 != 0 && bin.size() > 0) || bin.size() == 0){
		bin = '0' + bin;
	}
	int sign = 0;

	if (bin[0] == '1' && bin.size()==8) {
		string temp = "";
		sign = 1;
		for (int i = bin.length()-1; i >= 0; i--) {//从右往左数
			if (bin[i] == '1') {
				temp = bin[i] + temp;
				for (int j = i - 1; j >= 0; j--) {//左边所有数
					if (bin[j] == '0')
						temp = '1' + temp;
					else
						temp = '0' + temp;
				}
				break;
			}
			else
				temp = bin[i] + temp;
		}
		bin = temp;
	}

	for (int i = 0; i < bin.length(); i++) {
		result = result<< 1;
		result += (bin[i]-'0');
	}
	if (sign)
		return -1 * result;
	else
		return result;
}

string  binToHex(string bin) {
	bin = bin.substr(2, bin.length() - 2);
	//while (bin.length() < 8) {
	while ((bin.size() % 8 != 0 && bin.size() > 0) || bin.size() == 0) {
		bin = '0' + bin;
	}
	string hex="0x";
	string temp = "0B";
	int result = 0;
	for (int i = 0;i< bin.length() ;i++ ) {
		if (i % 4 == 3) {
			temp = temp + bin[i];
			result = binToInt(temp);
			hex = hex + intToChar(result);
			temp = "0B";
		}
		else
			temp = temp + bin[i];
	}
	return hex;
}

string intToHex(int integer) {
	string bin = intToBin(integer);
	return binToHex(bin);
}

string hexToBin(string hex) {
	string bin = "0B";
	string temp="";
	int integer = 0;
	hex = hex.substr(2, hex.length() - 2);
	for(int i=0;i<hex.length();i++){
		integer = charToInt(hex[i]);
		temp = intToBin(integer);//控制大于4位,在这里截断前面的
		temp = temp.substr( temp.length() - 4,4);
		bin = bin +temp;
	}	
	return bin;
}

int hexToInt(string hex) {
	string bin = hexToBin(hex);
	return binToInt(bin);
}

void checksums(vector<string> vec);

void readFromText(string filePath) {
	ifstream infile(filePath, ios::in);
	if (!infile) {
		cerr << "File couldn't be open" << endl;
	}
	vector<string>vec;
	char ch;
	cout << "文本读取到内容为";
	int time = 0;
	while (infile.get(ch)) {
		if (time % 5 == 0)
			cout << endl;
		time += 1;
		cout << ch << " : ";
		string hexNum = intToHex((int)ch);
		cout << hexNum << " " ;
		if (hexNum.length() == 1)
			hexNum = "0" + hexNum.substr(2, hexNum.length() - 2);
		else
			hexNum = hexNum.substr(2, hexNum.length() - 2);
		vec.push_back(hexNum);
	}
	if (vec.size() % 2 == 1) {
		vec.push_back("00");
	}
	infile.close();
	checksums(vec);
}

void checksums(vector<string> vec) {
	int data_sum = 0;
	string temp = "";
	cout << "\n16位数值如下:" << endl;
	for (int i = 0; i < vec.size(); i++) {
		if (i % 2 == 0) {
			temp = "0x" + vec[i];
		}
		else {
			temp += vec[i];
			cout << temp << " ";
			data_sum += hexToInt(temp);
		}
	}
	int maxValue = hexToInt(MAXVALE);
	int carry = data_sum / maxValue;
	int result = carry + data_sum % maxValue;
	cout << "\n校验码为" << intToHex(result) << endl;
}

int main(int args, char** argv) {
	string filePath;
	/*if (args > 1) {
		filePath = argv[1];
	}
	else {
		cout << "请输入正确的格式:xx.exe filePath" << endl;
	}*/
	 filePath = "C:\\Users\\Lenovo\\Desktop\\1.txt";
	readFromText(filePath);
	
}


在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

广大菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值