암호화프로그래밍/(Old)C-BIGINT(부록)

부록2. Visual Studio를 이용한 C 프로그래밍 예제

산을좋아한라쯔 2013. 6. 20. 23:18
반응형

여기서는 Visual Studio 2010을 이용해서 C 프로그래밍 하는 기초적인 방법을 설명한다.

 

Visual Studio는 주로 C#  혹은 C++ 프로그래밍을 하는데 사용되는데, C 프로그래밍에도 (당연히) 사용될 수 있다. 여기서는 2.1에서 소개한 큰 수에 대한 덧셈함수를 구현하고 테스트하는 것을 예제로해서, Visual Studio에서의 C 프로그래밍 방법을 소개하고자 한다.

 

1. 새 프로젝트 생성

    • Visual Studio를 실행하고, 파일/새로만들기/새 프로젝트 
    • 템플릿에서 Visual C++/빈프로젝트 선택하고,
      • 이름: Bigint_Add
      • 위치: 적당한 폴더 선택. 예제에서는 C개발용으로 미리 만들어 놓은 "C:\workspace_C" 선택함 

 

 

2. 헤더파일 bigint.h파일 생성

    • 솔루션 탐색기에서 "헤더 파일/추가/새 항목" 선택 

 

    • "Visual C++/코드/헤더파일(.h)"선택하고, 이름을 입력하고(biging.h), "추가"버튼 누른다.

 

3. bigint.h 코딩

bigint.h파일에 아래내용처럼 코딩

//01. CPU, 컴파일러에 따라서 조정할 값들
#define MAX_BIT_LEN 4096  //최대 비트수

 

typedef unsigned char u8; typedef unsigned short u16; typedef unsigned long u32; typedef unsigned long long u64;

 

#define BASE_IS_4_BYTES   #ifdef BASE_IS_4_BYTES typedef u32 INT; typedef u64 DINT; #define MAX_INT 0xffffffff #define BASE 0x100000000 #define MAX_DINT 0xffffffffffffffff #define MAX_POSITIVE 0x7fffffff #else typedef u16 INT; typedef u32 DINT; #define MAX_INT 0xffff #define BASE 0x10000 #define MAX_DINT 0xffffffff #define MAX_POSITIVE 0x7fff #endif

 

//02. 큰수(BIGINT)에 대한 정의들. CPU에 따라 재정의할 필요 없음 #define MAX_INT_LEN (MAX_BIT_LEN / (sizeof(INT) * 8) ) //INT자료형 최대 갯수 4096/32 = 128 typedef INT BIGINT[MAX_INT_LEN + 1]; //[0]위치에 크기정보 담고 있으므로 + 1

 

//03. 매크로들 #define SIZE(n) ((unsigned short)*(n))  #define SET_SIZE(n,m) (*(n) = (unsigned short)(m)) #define REMOVE_ZERO(n) while((SIZE(n)>0) && (*((n) + SIZE(n)) == 0)) --*(n);

 

//04. Error #define OK 0 #define E_Overflow -1 #define E_NotSupported -2 #define E_WrongFormat -3 #define E_ZeroLength -4 #define E_DivideByZero -5 #define E_Underflow -6

 

//05. 함수정의 int add(BIGINT A, BIGINT B, BIGINT C);

 

 

4. biging.c파일 생성

    • 솔루션 탐색기에서 "소스파일/추가/새항목"선택하고, 템플릿에서 "Visual C++/코드/C++파일(cpp)" 선택한 후, 이름 입력(biging.c) 후 "추가"버튼 누른다.     이 때, 파일이름의 확장자를 cpp가 아닌 c로 타이핑하는 것에 유의.

 

 

5. bigint.c 코딩

bigint.c파일에 아래 내용처럼 코딩

#include "bigint.h"
/**************************************************************************
주어진 BIGINT가 양수인지 판별
Input: @A: BIGINT to determine whether it's positive or not
Returns : 1 if BIGINT is positive value including zero
          -1 if BIGINT is negative value. 
***************************************************************************/
int isPositive(BIGINT A){
	if( (*A == MAX_INT_LEN) && (*(A+MAX_INT_LEN) > MAX_POSITIVE))
		return -1;
	else
		return 1;	
}

 

/*************************************************************************************** 두 수를 더함 만약 더한 두 수가 BIGINT의 최대자릿수를 넘어서는 경우는,  E_Overflow를 리턴하고, 결과에는 초과하는 부분을 절삭한 값 세팅 (음수 + 양수)의 경우에 해당 input: BIGINT A, BIGINT B output: BIGINT C (C = A + B) return: OK - if all ok E_Overflow - 두 수를 더한 값이 BIGINT의 최대값을 넘어서는 경우               ****************************************************************************************/ int add(BIGINT A, BIGINT B, BIGINT C){ INT *L, *S, *W; //w=sum INT *LE, *SE ; DINT t; INT k;//carry //S1.[자릿수 크기비교] large = (size(A) > size(B)) ==> A : B if(SIZE(A) > SIZE(B)){ L = A + 1; LE = A + SIZE(A); S = B + 1; SE = B + SIZE(B); SET_SIZE(C, SIZE(A)); }else{ L = B + 1; LE = B + SIZE(B); S = A + 1; SE = A + SIZE(A); SET_SIZE(C, SIZE(B)); } W = C +1; //S2.[초기화] k=0 k = (INT)0;  //S3. S4. 두 수 더하기. 오른쪽에서 왼쪽으로 until small_end while(S <= SE){ t = (DINT)*L++ + (DINT)*S++ + (DINT)k; *W++ = (INT)t; k = (INT)(t >> (sizeof(INT)*8) ); } //S5. S6. large값에다 carry 더하기 while(L <= LE){ t = (DINT)*L++ + (DINT)k; *W++ = (INT)t; k = (INT)(t >> (sizeof(INT)*8) ); } //S7. if carry exist(k > 0), C의 자릿수 1 증가 if(k > 0){ if( (SIZE(C)+1) > MAX_INT_LEN){  //max보다 큰 자릿수로 넘어가는 carry는 무시(즉, % BASE) REMOVE_ZERO(C); }else{ *W = 1; SET_SIZE(C, (SIZE(C))+1); } } //S8. Check overflow if((isPositive(A) == 1) && (isPositive(B) == 1) && (isPositive(C) == -1 )){ // (양수+양수) < 0 ==> overflow return E_Overflow; }else if((isPositive(A) == -1) && (isPositive(B) == -1) && (isPositive(C) == 1 )){ // (음수+음수) > 0 ==> overflow return E_Overflow; } return OK; }

 

 

 

6. test.c 파일 생성

    • 솔루션 탐색기에서 "소스파일/추가/새항목"선택하고, 템플릿에서 "Visual C++/코드/C++파일(cpp)" 선택한 후, 이름 입력(test.c) 후 "추가"버튼 누른다.     이 때, 파일이름의 확장자를 cpp가 아닌 c로 타이핑하는 것에 유의.

 

 

7. test.c 코딩

test.c파일에 아래 내용처럼 코딩

#include <stdio.h>
#include "bigint.h"
void main(){
	BIGINT a, b, c;
	//a: 3333 4444 aabb ccdd
	a[0]=2;
	a[1] = 0xaabbccdd;
	a[2] = 0x33334444;
	//b: 1122 3344 5566 7788 99aa bbcc
	b[0]=3;
	b[1] = 0x99aabbcc;
	b[2] = 0x55667788;
	b[3] = 0x11223344;
	//c = a + b
	// a:          3333 4444 aabb ccdd
	// b:1122 3344 5566 7788 99aa bbcc
	// c:1122 3344 8899 bbcd 4466 88a9
	add(a,b,c);
	//2 11223344 8899bbcd 446688a9
	printf("%x ",c[0]);
	printf("%x ",c[3]);
	printf("%x ",c[2]);
	printf("%x ",c[1]);
	printf("\n Press Enter to quit");
	getchar();
}

 

 

8. 빌드 및 실행

  • 메뉴에서 "빌드(B)/솔루션 빌드"를 눌러 솔루션 빌드해서 에러없이 빌드되는것 확인
    (아래 출력창이 자동으로 안보이는 경우는, 메뉴에서 "보기/출력"을 누르면 하단부에 출력창 나옴

 

 

  • 만약 빌드에서 실패가 있으면, 어떤 부분의 코딩이 잘못되었는지 확인 후 수정해서 다시 빌드
  • 메뉴에서 "디버그/디버그 시작하지 않고 시작"을 눌러서 프로그램 실행(혹은 Ctrl-F5)

 

  • 위 캡쳐화면처럼 값이 나오면 성공.

 

* 위 샘플에서, 헤더파일인 bigint.h를  "소스 파일"밑에 생성했는데, c소스와 헤더파일을 구분해주기 위해서는, biging.h를 "헤더 파일"밑에 생성하는 것이 좋겠다. 그렇지만, 샘플에서와 같이 "소스 파일"밑에 생성해도 실행하는데는 무방. 

다음 장 부터의 샘플에서는, 코드와 헤더 구분할 것임

 

 

 

반응형