基於計網作業---求文件校驗和--帶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);
	
}


在這裏插入圖片描述

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