상세 컨텐츠

본문 제목

1-6 체크섬을 구하는 문제

과제

by 근성 2021. 7. 9. 11:22

본문

문제설명 : 체크섬은 전송된 데이터와 일치하는지 확인하는것입니다.

체크섬은 sender, transmission, receiver 세가지 기능으로 구성됩니다.

1. sender함수에서 4자리 문자데이터를 통해 체크섬을 계산하고, transmission함수로 보내야합니다.  

2. sender함수에서 받은 문자열을 transmission에서는 오류를생성하고, receiver함수로 보내야합니다. 

3. receiver함수에서는 데이터를 검증하고 참인지 오류인지 확인을 합니다.

이번 과제 문제는 4자리의 수를 입력받고, 4자리의 수를 모두 더한 수의 일의자리수까지 합쳐서 data를 보내줍니다.

ex) 1234를 입력하면 1+2+3+4=10이므로 일의자리수가 0이되어 12340을 보내는 것입니다.

하지만 data를 보내는데에는 40%확률로 체크섬오류가 발생해야하는 문제조건이 있었습니다.

 

이 부분을 잘 감안해서 아래와 같은 접근방식을 잡았습니다.

주어진 문제를 풀기위해서는 난수개념아스키코드를 이용한 atoi itoa개념을 사용해야 했습니다.

 맨 처음에 메인함수에서 sender함수를 불러주고 sender함수에서 데이터를 입력받고 체크 섬을 계산하고 문자열로 변환해서 transmission으로 보내줬습니다.

 transmission함수에서는 매시도 마다 다른값을 받기위해 3번문제처럼srand time을 이용했고, 0,1,2,3,4 난수중 0,1이뜨면 에러가 뜨게 설정했습니다.(40%확률 에러) 

0,1이 뜰때, 몇번째 자릿수가 바뀔지도 index로 설정했고, const값을 바꿨습니다. const값 변경하기위해                   *(char*)&까지 사용한것도 확인 할 수 있습니다. 에러가 뜰경우 까지 생각해서 문자열에 넣고, receiver함수로 보내줍니다. 

receiver함수에서는 만약에 에러가 걸렸다면 에러가 걸리기전 체크섬과 걸린 후 체크섬을 비교해서 error를 출력하고 에러가 걸리지 않았다면, 에러가 걸리지 않았다고 출력하게 설정했습니다. 

#include<iostream>
#include<stdlib.h>//난수사용
#include<time.h>//매 시도 마다 다른값

using namespace std;

void Sender();
void Transmission_Process(const char* data);
void Receiver(const char* data);

int main()
{
	Sender();
}

void Sender()
{
	char data[6];//체크섬 문자열
	int num_send;
	int change_string;
	int semi_check = 0;
	int final_check = 0;
	int etc;
	cout<<"Data : ";
	cin >> num_send;//데이터 입력
	int copy_send = num_send;
	for (int i = 0; num_send != 0; i++)
	{
		etc = num_send % 10;
		num_send /= 10;
		semi_check = semi_check + etc;
	}
	final_check = semi_check % 10;
	copy_send = copy_send * 10 + final_check;
	cout << "Send Data:" << copy_send << endl; //체크섬 계산

	for (int i = 0; i < 5; i++)//문자열 변환
	{
		change_string = copy_send % 10;
		copy_send /= 10;
		data[4 - i] = change_string + '0';
	}

	data[5] = NULL;
	Transmission_Process(data);
}

void Transmission_Process(const char* data)
{
	int random = 0;
	int luck;
	int index;
	srand((unsigned int)time(NULL));//매시도 마다 다른값
	luck = rand() % 4 + 0;//40%확률
	index = rand() % 3 + 0;//index번째 자릿수 바꾸기

	if (luck <= 1)
	{
		random = rand() % 9 + 1;//index번째 random으로 바꾸기
		*(char*)&data[index] = random + '0';//const값 건드리기 위해
	}


	Receiver(data);
}

void Receiver(const char* data)
{
	int before_sum;
	int after_sum;
	int atoi_data = 0;

	cout << "Received Data:" << data << endl;

	before_sum = data[4] - '0';//바뀌기전 체크섬을 int형으로 

	for (int i = 0; i < 4; i++)
	{
		atoi_data = data[3 - i] - '0' + atoi_data;//data값의 나머지(바뀐후 체크섬)
	}

	after_sum = atoi_data % 10;//바뀐 후 체크섬을 int형으로

	if (after_sum == before_sum)//바뀌기전과 같다면
	{
		cout<< before_sum<< "=="<<after_sum<< "\tError is not Occured!"<< endl;
	}
	else//바뀌기 전과 다르다면
		cout << before_sum << "!=" << after_sum << "\tError!"<<endl;

}

 

코드 실행 결과 사진

정리 : data[0],data[1],data[2],data[3] 을 첨에 입력받은데이터(혹은 에러걸려서 바뀐 데이터) data[4]는 바뀌기전 체크섬(에러걸리거나, 안걸리거나) 에러가 걸렸다면 receiver함수에서 data[0]~data[3]까지 수를 더해서 나머지(바뀐 체크섬)를 data[4](바뀌기전 체크섬)와 비교해서 에러(40%)인지 아닌지(60%)를 출력했습니다. 만약 에러가 뜨지않았다면 data[4]와 receiver함수가 받은 data[0]~data[3]까지 수를 더해서 나머지가 같으므로 에러가 발생하지 않게 했습니다.

하지만 저는 이 코드가 0.2점 감점 되었습니다.

왜일까요?

감점 요인 질문

이러한 이유가 있었습니다.

속으로는 안타깝지만, 제가 문제를 잘 못 이해한거기때문에 제 잘못입니다 ㅠㅠ

어떤 점을 보완해야하냐면 에러가 나더라도 1/9확률로 똑같을 수가 있어서 똑같은 수가 나올경우에는 다시 난수를 돌리게 했어야만 했습니다.

이번문제의 후기는 코드를 작성하는데 머리를 많이 사용했지만, 1차과제 문제중에서 제일 재밌었던 문제였습니다. 0.2점은 아쉽지만 checksum의 개념도 알 수 있었고, 직접 구현할 수도있어서 정말 뿌듯했던 문제였습니다.

#이 문제의 출처는 kw대학교 컴퓨터정보공학부 2021년 1학기 객체지향프로그래밍 과제문제입니다.

관련글 더보기

댓글 영역