/*
* http://sosal.tistory.com/
* made by so_Sal
*/
/*
* 이 포스팅을 이해하기 위해선
* c언어 srand(), time(), rand() 함수들
* 리눅스 read write 파일 시스템콜 뿐만 아니라
* fork(), execl(), pipe(), dup2() 프로세스 시스템콜을
* 미리 아셔야 이해할 수 있습니다./
*/
예전에 숫자 맞추는 게임(?)이 널루트 가입문제로 나왔었던 기억이..있습니다 ㅎㅎ
아마 억대자리수 덧셈이었나?? 그럴텐데.. 기억이 잘 안나네요.
(동아리 선배분께서 열심히 풀고계신걸 잠깐 본적이 ㅎㅎㅎ)
여튼, 번뜩 생각나서 고걸 부셔버리는걸로.. 한번 포스팅 해보려고 합니다.
목적은 1초안에 1만자리수 덧셈문제를 풀기! 입니다.
srand()함수와 rand()함수는 다 아실거라 믿고...
srand()에 보통 time(0)를 넣죠?
#include <time.h>
time_t time(time_t *t);
time - 초 단위로 시간을 얻는다.
//man page 참조
초 단위로 시간을 얻는다는 말은, 즉 1초 간격으로 난수 테이블의 같은 시드값을 리턴한다는 말..
// gcc rand.c -o rand
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(){
srand(time(NULL));
int a = rand()%10000
printf("%d",a);
return 0;
}
엄청 열심히, 빠르게!! 위 프로그램을 실행시켰습니다 -.-;;
역시 1초 단위로 rand()는 같은값을 리턴하네요..
덕분에 이 결과로 srand()시드값이 time(NULL)에 의해
1초간 같은 결과를 리턴한다는 사실을 확실하게 알 수 있었습니다.
그럼 이 원리를 통해.. 숫자 맞추기 게임을 풀 수 있겠습니다 ㅇ_ㅇ;
#include<stdio.h>
#include<time.h>
int main(){
srand(time(0)); //1초 간격으로 같은 시드값 리턴
printf("====== Speed math test!! ======\n");
int operand1 = rand() / 100000;
int operand2 = rand() / 100000;
int input;
int result = operand1 + operand2;
alarm(1); //제한시간 1초 -.-;
printf("%d + %d = ?\n",operand1,operand2);
scanf("%d",&input);
if( result == input ) //정답확인
printf("success!\n");
else
printf("fail..!\n");
return 0;
}
실행해보았습니다.
1초만에 풀려고하니 alarm(1) , 1초 알람신호 때문에 왠만한 산수천재 아니고선..;;
그리고 찍짜하니..;; 답이없고 ㅠㅠ
하지만 우리는, 프로그래머 아닙니까? :-)
프로그래밍으로 풀어봅시다 +_+
/*
* srand( time(0) )을 메인함수에서 일단 실행합니다.
* 이로써, 곧 만들 프로그램은 math 문제와 같은 rand 시드를 가지고 시작합니다.
* 2개의 pipe를 생성한 후, 자식 프로세스를 만듭니다.
* dup2를 이용하여 자식프로세스의 표준입력을 input-pipe로,
* dup2를 이용하여 자식프로세스의 표준출력을 output-pipe로 설정합니다.
* execl 시스템콜을 이용하여 자식프로세스를 문제의 프로그램 math로 바꿔버립니다.
* rand 시드가 똑같으니, 같은 결과값을 맞출 수 있습니다.
* 그 답을 자식프로세스 (즉 math)에게 넘기면 문제 성공!
*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdlib.h>
#include<time.h>
int main(){
srand(time(0));
int pid;
int input[2]; // 부모에서 math 프로그램으로 입력할 파이프
int output[2]; // math 프로그램이 출력하는 문자열을 건넬 파이프
char buffer[BUFSIZ];
if( pipe(input) !=0 ){
perror("pipe error\n");
exit(EXIT_FAILURE);
}
if( pipe(output) != 0){
perror("pipe error\n");
exit(EXIT_FAILURE);
} // 입출력 파이프 2개 생성 완료
pid = fork();
if(pid == -1){
}
else if(pid == 0){
//child process
dup2(input[1],1); //input to STDIN
dup2(output[0],0); // output to STDOUT
execl("./math","math",0);
perror("execl error\n"); //execl 실패시 에러 출력
exit(EXIT_FAILURE);
}
//parent process
int count;
int oper1,oper2;
oper1 = rand() / 100000;
oper2 = rand() / 100000;
sprintf(buffer,"%d",oper1+oper2); //문제의 프로그램의 답 알아내는 과정
write(output[1],buffer,BUFSIZ);
while(1){
count = read(input[0],buffer,BUFSIZ);
printf("%s\n",buffer); //답 전달
break;
}
return 0;
}
'Linux > Linux_technic' 카테고리의 다른 글
Checksum과 md5sum / 파일 검사합 (0) | 2014.08.12 |
---|---|
/proc/pid/maps : 파일 프로세스의 메모리 공간 (4) | 2011.01.29 |
bof를 이용하여 함수포인터 공략하기 (0) | 2010.11.06 |
Strcmp 부분 gdb로 암호 문자열 크랙하기 (0) | 2010.08.29 |
Linux :: Strace - 시스템콜과 신호 추적 (1) | 2010.03.04 |