/*
 * 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 |