• Control Panel
  • Write a Post

  • Home
  • Cover
  • Notice
  • Tag List
  • Location Log
  • Keywords
  • Guest Book
  • Lines

VC 9.0에서 Crypto++ Library를 이용하여 SHA256(SHA2) 구하기

  • Posted at 2012/01/25 18:49
  • Filed under 라이브러리
  • RSS Icon ATOM Icon

바이너리의 무결성 체크를 위해 hash를 사용하는데,
주로 SHA를 이용합니다.
최근에 현업에서 SHA256(혹은 SHA2)의 요구조건이 있는데,
불행하게도 Win32 API로는 SHA2를 구하는데 제약사항이 있습니다.
(ALG_ID(링크)를 보면, SHA256은 대체적으로 Vista 이상의 OS에서 지원됩니다.)
 
그래서, SHA256을 직접 구현해야 되는데,
문제는 "버그"입니다. 즉, Hash라는 중요한 모듈에 버그가 있다면, 큰일날 노릇이죠.
그래서 안정성있는 코드를 사용하는것은 무었보다도 중요합니다.
 
보통 openssl에도 sha256이 있는데,
openssl은,
•빌드가 쉽지않다. (즉, SHA256 부분만 가져오기가 힘들다)
•라이선스가 좀 까다롭다

와 같은 제약이 있습니다.
 
그래서 알아본 결과 crypto++ 이라는 라이브러리가 있던데,
FIPS-2 Level 1 통과도 되었으니, 나름 안정성있는 코드라 봅니다.
물론 Public Domain이라 사용 제한도 없구요.
 
문제는, crypto++를 가져오고 빌드하는 문제입니다.
물론, crypto++도 VC 빌드가 있으나,
전체가 아니라, sha256 부분만 가져오도록 하는것이 본 블로그 포스트의 목적입니다.
 
빌드를 완성시킨, sha256을 공유하니 확인해 보시기 바랍니다.
우선, x64 platform까지 추가된 프로젝트를 가정하고,
상위 경로에 Common에 CryptoppSHA256.cpp/.h가 Main Body이며,
상위 경로에 OpenSrc\cryptopp561에 crypto++ 코드가 들어있다고 가정합니다.
 
개발의 귀차니즘으로 CryptoppSHA256.cpp는 CString을 사용하는데,
ATL 정도만 Link하면 빌드가 됩니다.
물론, ATL 사용이 어렵다면, CString 대신 TCHAR buffer가 들어가도록 구현하세요.
그러면 순수 C++로 구현이 될 것입니다.
 
우선, 아래와 같이 crypto++의 .cpp 코드를 가져오기 합니다.
물론, SHA256 실행을 위한 최소한의 코드입니다.

사용자 삽입 이미지
위와 같은 cpp 목록의 속성을 들어가 precompile header를 Off 시킵니다.
이런 작업은 되도록 All Configuration & All Platfoms로 하시기 바랍니다.
사용자 삽입 이미지

그리고, 아래의 2개의 cpp를 추가합니다. 물론, precompile header도 Off 시킵니다.
사용자 삽입 이미지
그리고 위 2개의 파일을 X64에서만 빌드되도록 합니다.
즉, 위 2개의 파일의 속성에서, All Configurations & Win32 조합으로, Excluded From Build를 Yes합니다.
사용자 삽입 이미지
그리고, x64dll.asm을 추가합니다.
사용자 삽입 이미지

위와 같이 창이 뜨면 Cancel 하시기 바랍니다.

x64dll.asm도 아까전의 2개 파일처럼 x64에서만 빌드되도록 합니다.

그리고, 마지막으로, 프로젝트의 .vcproj에서 x64dll.asm이 선언된 부분을 아래의 내용으로 overwrite합니다.
(tab이 깨지는데, 정확한 내용은 sha256.zip::CrpytoSHA256\CrpytoSHA256.vcproj를 참고하세요)

<File
RelativePath="..\OpenSrc\cryptopp561\x64dll.asm"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="ml64.exe /c /nologo /Fo&quot;$(IntDir)\x64dll.obj&quot; /Zi &quot;$(InputPath)&quot;&#x0D;&#x0A;"
Outputs="$(IntDir)\x64dll.obj"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="ml64.exe /c /nologo /Fo&quot;$(IntDir)\x64dll.obj&quot; /Zi &quot;$(InputPath)&quot;&#x0D;&#x0A;"
Outputs="$(IntDir)\x64dll.obj"
/>
</FileConfiguration>
</File>

이렇게 하면, Win32와 x64모두 빌드가 됩니다.
 
첨부된 sample은 "abc"에 대한 sha256 값을 검증하는 내용입니다.
코드는,
#include "CryptoppSHA256.h"
...
CString strSHA256;
...
CCryptoppSHA256::GetSHA256AndVerify((LPBYTE)"abc", 3, strSHA256);
와 같이 하면 됩니다.
리턴값은 Win32 ErrorCode입니다.
 
CString을 사용하기 때문에, ATL이나 MFC를 사용합니다.
물론, TCHAR 버퍼를 사용하도록 코드 수정 하면 해당 의존성은 제거될 것입니다.
 
cryptopp561의 testvectors 경로에 sha.txt가 있습니다.
그곳의 내용으로 verify할 수 있습니다.
물론, Win32 / x64 모두 제대로 동작함을 알 수 있습니다.

sha256.zip
출처 : http://greenfishblog.tistory.com/116

크리에이티브 커먼즈 라이센스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by 달빛

2012/01/25 18:49 2012/01/25 18:49
Tag
Crypto++, SHA, SHA2, SHA256, 암호화
Response
No Trackback , No Comment
RSS :
http://sinwoong.co.kr/tc/sinwoong/rss/response/24

Trackback URL : http://sinwoong.co.kr/tc/sinwoong/trackback/24

C++ STL 프로그래밍(10) - 알고리즘 : (2)

  • Posted at 2012/01/12 18:31
  • Filed under C, C++, STL
  • RSS Icon ATOM Icon
사용자 삽입 이미지
이전 회에는 STL 알고리즘들 중 비슷한 성격의 알고리즘을 모아서 '변경 불가 시퀀스 알고리즘', '변경 가능 시퀀스 알고리즘', '정렬 관련 알고리즘', '범용 수치 알고리즘'으로 크게 네 개로 나누고 이중 '변경 불가 시퀀스 알고리즘' 과 '변경 가능 시퀀스 알고리즘'에 있는 주요 알고리즘의 특징과 사용 방법에 대해서 설명하였습니다.

이번 회는 이전 회에 설명하지 못한 '정렬 관련 알고리즘' 과 '범용 수치 알고리즘'의 주요 알고리즘의 특징과 사용 방법에 대해서 설명하겠습니다.

10.1. 정렬 관련 알고리즘

10.1.1 sort

sort는 컨테이너에 있는 데이터들을 내림차순 또는 오름차순으로 정렬 할 때 가장 자주 사용하는 알고리즘입니다. 컨테이너에 저장하는 데이터의 자료 형이 기본형이라면 STL에 있는 greate나 less 비교 조건자를 사용합니다(STL의 string의 정렬에도 사용할 수 있습니다. 다만 이 때는 알파벳 순서로 정렬합니다). 기본형이 아닌 경우에는 직접 비교 조건자를 만들어서 사용해야 합니다.

sort의 원형
template<class RandomAccessIterator>
   void sort( RandomAccessIterator _First, RandomAccessIterator _Last );
첫 번째와 두 번째 파라미터는 정렬하려는 구간의 시작과 마지막을 가리키는 반복자입니다. 비교 조건자를 필요로 하지 않고 기본형을 저장한 컨테이너를 오름차순으로 정렬합니다.
template<class RandomAccessIterator, class Pr>
   void sort( RandomAccessIterator _First, RandomAccessIterator _Last, BinaryPredicate _Comp );
첫 번째와 두 번째 파라미터는 정렬하려는 구간의 시작과 마지막을 가리키는 반복자입니다. 세 번째 파라미터는 정렬 방법을 기술한 비교 조건자입니다.

sort 알고리즘의 원형을 보면 알 수 있듯이 램덤 접근 반복자를 지원하는 컨테이너만 sort 알고리즘을 사용할 수 있습니다.

sort 사용 방법
vector<int> vec1;
…..
// 오름차순 정렬
sort( vec1.begin(), vec1.end() );

// 내림차순 정렬
Sort( vec1.begin(), vec1.end(), greater<int>() );
< 리스트 1. less와 greater 비교 조건자를 사용한 sort >
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

int main()
{
  vector<int> vec1(10);
  vector<int> vec2(10);
  vector<int> vec3(10);
  vector <int>::iterator Iter1;

  generate( vec1.begin(), vec1.end(), rand );
  generate( vec2.begin(), vec2.end(), rand );
  generate( vec3.begin(), vec3.end(), rand );

  // 오름차순 정렬
  cout << "vec1 정렬 하기 전" << endl;
  for( Iter1 = vec1.begin(); Iter1 != vec1.end(); ++Iter1 ) {
    cout << *Iter1 << ", ";
  }
  cout << endl;

  sort( vec1.begin(), vec1.end() );
  
  cout << "vec1 오름차순 정렬" << endl;
    for( Iter1 = vec1.begin(); Iter1 != vec1.end(); ++Iter1 ) {
    cout << *Iter1 << ", ";
  }
  cout << endl;
  cout << endl;

  // 내림차순 정렬
  cout << "vec2 정렬 하기 전" << endl;
  for( Iter1 = vec2.begin(); Iter1 != vec2.end(); ++Iter1 ) {
    cout << *Iter1 << ", ";
  }
  cout << endl;
  
  sort( vec2.begin(), vec2.end(), greater<int>() );

  cout << "vec2 내림차순 정렬" << endl;
    for( Iter1 = vec2.begin(); Iter1 != vec2.end(); ++Iter1 ) {
    cout << *Iter1 << ", ";
  }
  cout << endl;
  cout << endl;

  // 일부만 내림차순 정렬
  cout << "vec3 정렬 하기 전" << endl;
  for( Iter1 = vec3.begin(); Iter1 != vec3.end(); ++Iter1 ) {
    cout << *Iter1 << ", ";
  }
  cout << endl;

  sort( vec3.begin() + 5, vec3.end(), greater<int>() );

  cout << "vec3 일부만 내림차순 정렬" << endl;
    for( Iter1 = vec3.begin(); Iter1 != vec3.end(); ++Iter1 ) {
    cout << *Iter1 << ", ";
  }
  cout << endl;

  return 0;
}
< 결과 >



<리스트 1>은 기본 형 데이터를 정렬하는 예제로 이번에는 유저 정의 형 데이터를 정렬하는 예제를 보여 드리겠습니다.

< 리스트 2. USER 구조체의 Money를 기준으로 정렬 >
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

struct USER
{
  int UID;
  int Level;
  int Money;
};

struct USER_MONEY_COMP
{
  bool operator()(onst USER& user1, const USER& user2)
  {
    return user1.Money > user2.Money;
  }
};

int main()
{
  USER User1; User1.UID = 1;  User1.Money = 2000;
  USER User2; User2.UID = 2;  User2.Money = 2050;
  USER User3; User3.UID = 3;  User3.Money = 2200;
  USER User4; User4.UID = 4;  User4.Money = 1000;
  USER User5; User5.UID = 5;  User5.Money = 2030;

  vector<USER> Users;
  Users.push_back( User1 );  Users.push_back( User2 );
  Users.push_back( User3 );  Users.push_back( User4 );
  Users.push_back( User5 );

  vector <USER>::iterator Iter1;

  cout << "돈을 기준으로 정렬 하기 전" << endl;
  for( Iter1 = Users.begin(); Iter1 != Users.end(); ++Iter1 ) {
    cout << Iter1->UID << " : " << Iter1->Money << ", ";
  }
  cout << endl << endl;

  sort( Users.begin(), Users.end(), USER_MONEY_COMP() );

  cout << "돈을 기준으로 내림차순으로 정렬" << endl;
  for( Iter1 = Users.begin(); Iter1 != Users.end(); ++Iter1 ) {
    cout << Iter1->UID << " : " << Iter1->Money << ", ";
  }
  cout << endl << endl;

  return 0;
}
< 결과 >

사용자 삽입 이미지


10.1.2. binary_search

이미 정렬 되어 있는 것 중에서 특정 데이터가 지정한 구간에 있는지 조사하는 알고리즘입니다. 이것도 sort와 같이 비교 조건자가 필요 없는 버전과 필요한 버전 두 개가 있습니다(단 sort와 다르게 랜덤 접근 반복자가 없는 컨테이너도 사용할 수 있습니다).

binary_search 원형
template<class ForwardIterator, class Type>
   bool binary_search( ForwardIterator _First, ForwardIterator _Last, const Type& _Val );

template<class ForwardIterator, class Type, class BinaryPredicate>
   bool binary_search( ForwardIterator _First, ForwardIterator _Last, const Type& _Val, 
                        BinaryPredicate _Comp );
binary_search 사용 방법
vector<int> vec1;
…..
sort( vec1.beign(), vec1.end() );
…...
bool bFind = binary_search( vec1.begin(), vec1.end(), 10 );
binary_search는 정렬한 이후에 사용해야 한다고 앞서 이야기 했습니다. 만약 정렬하지 않고 사용하면 어떻게 될까요?

< 리스트 3. 정렬하지 않고 binary_search 사용 >
int main()
{
  vector<int> vec1;
  vec1.push_back(10);  vec1.push_back(20);  vec1.push_back(15);
  vec1.push_back(7);  vec1.push_back(100); vec1.push_back(40);
  vec1.push_back(11);  vec1.push_back(60);  vec1.push_back(140);

  bool bFind = binary_search( vec1.begin(), vec1.begin() + 5, 15 );
  if( false == bFind ) {
    cout << "15를 찾지 못했습니다." << endl;
  } else {
    cout << "15를 찾았습니다." << endl;
  }

  return 0;
}
디버그 모드로 빌드 후 실행 하면 아래와 같은 에러 창이 나옵니다.

사용자 삽입 이미지


에러 내용은 시퀀스가 정렬되지 않았다고 나옵니다. 릴리즈 모드 빌드 후 실행하면 위와 같은 에러는 나오지 않지만 결과는 false가 나옵니다.

binary_search를 사용할 때는 꼭 먼저 정렬해야 한다는 것을 잊지 말기를 바랍니다.

< 리스트 4. 정렬 후 binary_search 사용 >
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

int main()
{
  vector<int> vec1;
  vec1.push_back(10);  vec1.push_back(20);  vec1.push_back(15);
  vec1.push_back(7);  vec1.push_back(100); vec1.push_back(40);
  vec1.push_back(11);  vec1.push_back(60);  vec1.push_back(140);

  sort( vec1.begin(), vec1.end() );

  bool bFind = binary_search( vec1.begin(), vec1.begin() + 5, 15 );
  if( false == bFind ) {
    cout << "15를 찾지 못했습니다." << endl;
  } else {
    cout << "15를 찾았습니다." << endl;
  }

  return 0;
}
< 결과 >

사용자 삽입 이미지


비교 조건자를 사용하는 경우는 위의 <리스트 2> 코드를 예를들면 <리스트 2>에서 사용했던 USER_MONEY_COMP 조건자를 사용합니다.

< 리스트 4. 리스트 2의 Users를 binary_search에 사용 >
…….
sort( Users.begin(), Users.end(), USER_MONY_COMP() );
bool bFind = binary_search( Users.begin(), Users.begin() + 3, User5, USER_MONY_COMP() );
…….
10.1.3 merge

두 개의 정렬된 구간을 합칠 때 사용하는 것으로 두 구간과 겹치지 않은 곳에 합친 결과를 넣어야 합니다. 주의해야 할 점은 합치기 전에 이미 정렬이 되어 있어야 하며 합친 결과를 넣는 것은 합치는 것들과 겹치면 안되며, 또한 합친 결과를 넣을 수 있는 공간을 확보하고 있어야 합니다.

merge의 원형
template<class InputIterator1, class InputIterator2, class OutputIterator>
   OutputIterator merge( InputIterator1 _First1, InputIterator1 _Last1,
      InputIterator2 _First2, InputIterator2 _Last2, OutputIterator _Result
   );

template<class InputIterator1, class InputIterator2, class OutputIterator, class BinaryPredicate>
   OutputIterator merge( InputIterator1 _First1, InputIterator1 _Last1,
    InputIterator2 _First2, InputIterator2 _Last2, OutputIterator _Result, BinaryPredicate _Comp );
merge 사용 방법
vector<int> vec1, vec2, vec3;
…..
merge( vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), vec3.begin() );
아래의 <리스트 5>는 vec1과 vec2를 합쳐서 vec3에 넣는 것으로 vec1과 vec2는 이미 정렬되어 있고 vec3는 이 vec1과 vec2의 크기만큼의 공간을 미리 확보해 놓고 있습니다.

< 리스트 5. 두 개의 vector의 merge >
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

int main()
{
  vector <int>::iterator Iter1;
  vector<int> vec1,vec2,vec3(12);
  
  for( int i = 0; i < 6; ++i )
    vec1.push_back( i );

  for( int i = 4; i < 10; ++i )
    vec2.push_back( i );
  
  cout << "vec1에 있는 값" << endl;
  for( Iter1 = vec1.begin(); Iter1 != vec1.end(); ++Iter1 ) {
    cout << *Iter1 << ", ";
  }
  cout << endl;

  cout << "vec2에 있는 값" << endl;
  for( Iter1 = vec2.begin(); Iter1 != vec2.end(); ++Iter1 ) {
    cout << *Iter1 << ", ";
  }
  cout << endl;


  merge( vec1.begin(), vec1.end(), 
      vec2.begin(), vec2.end(), 
      vec3.begin() );

  cout << "vec1과 vec2를 merge한 vec3에 있는 값" << endl;
  for( Iter1 = vec3.begin(); Iter1 != vec3.end(); ++Iter1 ) {
    cout << *Iter1 << ", ";
  }
  cout << endl;

  return 0;
}
< 결과 >

사용자 삽입 이미지


정렬 관련 알고리즘은 위에 소개한 세 개 이외에도 더 있지만 지면 관계상 보통 자주 사용하는 sort, binary_search, merge 세 개를 소개하는 것으로 마칩니다. 제가 소개하지 않은 정렬 관련 알고리즘을 더 공부하고 싶은 분들은 MSDN이나 C++ 책을 통해서 공부하시기를 바랍니다.

10.2. 범용 수치 알고리즘

10.2.1 accumulate

지정한 구간에 속한 값들을 모든 더한 값을 계산합니다. 기본적으로 더하기 연산만 하지만 조건자를 사용하면 더하기 이외의 연산도 할 수 있습니다. accumulate를 사용하기 위해서는 앞서 소개한 알고리즘과 다르게 <numeric> 헤더 파일을 포함해야 합니다.

accumulate의 원형
template<class InputIterator, class Type>
   Type accumulate( InputIterator _First, InputIterator _Last, Type _Val );
첫 번째와 두 번째 파라미터는 구간이며, 세 번째 파라미터는 구간에 있는 값에 더할 값입니다.
template<class InputIterator, class Type, class BinaryOperation>
 Type accumulate( InputIterator _First, InputIterator _Last, Type _Val, BinaryOperation _Binary_op );
네 번째 파라미터는 조건자로 조건자를 사용하여 기본 자료 형 이외의 데이터를 더할 수 있고, 더하기 연산이 아닌 다른 연산을 할 수도 있습니다.

accumulate 사용 방법
vector<int> vec1;
…..
// vec1에 있는 값들만 더 한다.
int Result = accmulate( vec1.begin(), vec1.end(), 0, );
아래의 <리스트 6>은 int를 저장하는 vector를 대상으로 accmurate를 사용하는 가장 일반적인 예입니다.

< 리스트 6. vector에 있는 값들을 계산 >
#include <vector>
#include <iostream>
#include <numeric>

using namespace std;

int main()
{
  vector <int>::iterator Iter1;
  vector<int> vec1;

  for( int i = 1; i < 5; ++i )
    vec1.push_back( i );

  // vec1에 있는 값
  for( Iter1 = vec1.begin(); Iter1 != vec1.end(); ++Iter1 ) {
    cout << *Iter1 << ", ";
  }
  cout << endl;


  // vec1에 있는 값들을 더한다.
  int Result1 = accumulate( vec1.begin(), vec1.end(), 0 );
  // vec1에 있는 값들을 더한 후 10을 더 한다.
  int Result2 = accumulate( vec1.begin(), vec1.end(), 10 );

  cout << Result1 << ", " << Result2 << endl;
}
< 결과 >

사용자 삽입 이미지


이번에는 조건자를 사용하여 유저 정의형을 저장한 vector를 accmulate에서 사용해 보겠습니다. 이번에도 더하기 연산만을 했지만 조건자를 사용하면 곱하기 연산 등도 할 수 있습니다.

< 리스트 7. 조건자를 사용한 accumulate >
#include <vector>
#include <iostream>
#include <numeric>

using namespace std;

struct USER
{
  int UID;
  int Level;
  int Money;
};

struct USER_MONY_ADD
{
  USER operator()(const USER& user1, const USER& user2)
  {
    USER User;
    User.Money = user1.Money + user2.Money;
    return User;
  }
};

int main()
{
  USER User1; User1.UID = 1;  User1.Money = 2000;
  USER User2; User2.UID = 2;  User2.Money = 2050;
  USER User3; User3.UID = 3;  User3.Money = 2200;
  USER User4; User4.UID = 4;  User4.Money = 1000;
  USER User5; User5.UID = 5;  User5.Money = 2030;

  vector<USER> Users;
  Users.push_back( User1 );  Users.push_back( User2 );
  Users.push_back( User3 );  Users.push_back( User4 );
  Users.push_back( User5 );

  vector <USER>::iterator Iter1;

  for( Iter1 = Users.begin(); Iter1 != Users.end(); ++Iter1 ) {
    cout << Iter1->UID << " : " << Iter1->Money << ", ";
  }
  cout << endl << endl;

  // Users에 있는 Money 값만 더하기 위해 Money가 0인 InitUser를 세 번째 파라미터에
  // 조건자를 네 번째 파라미터로 넘겼습니다.
  USER InitUser; InitUser.Money = 0;
  USER Result = accumulate( Users.begin(), Users.end(), InitUser, USER_MONY_ADD() );
  cout << Result.Money << endl;
}
< 결과 >

사용자 삽입 이미지


10.2.2 inner_product

두 입력 시퀀스의 내적을 계산하는 알고리즘으로 기본적으로는 +와 *을 사용합니다. 두 입력 시퀀스의 값은 위치의 값을 서로 곱한 값을 모두 더 한 것이 최종 계산 값이 됩니다. 주의 해야 할 것은 두 입력 시퀀스의 구간 중 두 번째 시퀀스는 첫 번째 시퀀스 구간 보다 크거나 같아야 합니다. 즉 첫 번째 시퀀스 구간의 데이터는 5개가 있는데 두 번째 시퀀스에 있는 데이터가 5개 보다 작으면 안됩니다.

inner_product의 원형
template<class InputIterator1, class InputIterator2, class Type>
   Type inner_product( InputIterator1 _First1, InputIterator1 _Last1, InputIterator2 _First2, 
      Type _Val );
조건자를 사용하는 버전으로 조건자를 사용하면 유저 정의형을 사용할 수 있는 내적 연산 방법을 바꿀 수 있습니다.
template<class InputIterator1, class InputIterator2, class Type,
   class BinaryOperation1, class BinaryOperation2>
   Type inner_product( InputIterator1 _First1, InputIterator1 _Last1, InputIterator2 _First2, 
      Type _Val, BinaryOperation1 _Binary_op1, BinaryOperation2 _Binary_op2 );
아래의 <리스트 8>은 조건자를 사용하지 않는 inner_product를 사용하는 것으로 vec1과 vec2의 내적을 계산합니다.

< 리스트 8. inner_product를 사용하여 내적 계산 >
#include <vector>
#include <iostream>
#include <numeric>

using namespace std;

int main()
{
  vector<int> vec1;
  for( int i = 1; i < 4; ++i )
    vec1.push_back(i);

  vector<int> vec2;
  for( int i = 1; i < 4; ++i )
    vec2.push_back(i);

  int Result = inner_product( vec1.begin(), vec1.end(), vec2.begin(), 0 );
  cout << Result << endl;

  return 0;
}
< 결과 >

사용자 삽입 이미지


<리스트 8>의 vec1과 vec2에는 각각 1, 2, 3 의 값이 들어가 있습니다. 이것을 네 번째 파라미터의 추가 값을 0을 넘긴 inner_droduct로 계산하면

14 = 0 + (1 * 1) + (2 * 2) + (3 * 3);

가 됩니다.

<리스트 8>의 코드를 보기 전에는 어떻게 계산 되는지 잘 이해가 되지 않는 분들은 <리스트 8> 코드를 보면 inner_product가 어떻게 계산 되는지 쉽게 이해할 수 있을 것입니다.

inner_product도 다른 알고리즘처럼 조건자를 사용할 수 있습니다. 제가 앞서 다른 알고리즘에서 조건자를 사용한 예를 보여 드렸으니 inner_product에서 조건자를 사용하는 방법은 숙제로 남겨 놓겠습니다.^^

범용 수치 알고리즘에는 위에 설명한 accmulate와 inner_product 이외에도 더 있지만 다른 것들은 보통 사용 빈도가 높지 않고 그것들을 다 소개하기에는 많은 지면이 필요로 하므로 이것으로 끝내겠습니다.^^;

범용 수치 알고리즘을 끝으로 STL의 알고리즘을 설명하는 것을 마치겠습니다. 이전 회와 이번에 걸쳐서 소개한 알고리즘은 STL에 있는 알고리즘 중 사용 빈도가 높은 알고리즘들로 이 것 이외에도 많은 알고리즘이 있으니 제가 설명한 알고리즘을 공부한 후에는 제가 설명하지 않은 알고리즘들도 공부하시기를 바랍니다.

지금까지 제가 설명한 글들을 보시면 STL은 사용할 때 일관성이 높다라는 것을 알 수 있을 것입니다. 높은 일관성 덕분에 하나를 알면 그 다음은 더 쉽게 알 수 있습니다.

C++의 STL은 결코 사용하기 어려운 것이 아닙니다. C++을 알고 있다면 아주 쉽게 공부할 수 있으며 STL을 사용함으로 더 쉽고 견고하게 프로그래밍할 수 있습니다. 그러나 STL의 컨테이너나 알고리즘에 대해서 잘 모르면서 다른 사람들이 사용한 코드를 보고 그냥 사용하면 STL이 독이 될 수도 있음을 조심해야 합니다.

저는 몇 달 전부터 C++0x을 공부하고 있습니다. C++0x는 현재 개발중인 새로운 C++ 표준입니다. C++0x에는 지금의 C++을 더 강력하고 쉽게 사용할 수 있게 해 주는 다양한 것들이 있습니다. 이 중 lambda라는 것이 있는데 이것을 사용하면 알고리즘에서 조건자를 사용할 때 지금보다 훨씬 더 편하게 기술할 수 있습니다. STL을 공부한 이 후에는 C++0x을 공부하시기를 바랍니다.

출처 : http://www.hanb.co.kr/network/view.html?bi_id=1627
크리에이티브 커먼즈 라이센스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

"C, C++, STL" 분류의 다른 글

C++ STL 프로그래밍(9) - 알고리즘 : (1)
C++ STL 프로그래밍(8) - 셋(Set)
C++ STL 프로그래밍(7) - 맵(Map)
C++ STL 프로그래밍(6) - 해시 맵(Hash Map)
C++ STL 프로그래밍(5) - 덱(deque) : (2)

Posted by 달빛

2012/01/12 18:31 2012/01/12 18:31
Tag
STL, 알고리즘
Response
No Trackback , No Comment
RSS :
http://sinwoong.co.kr/tc/sinwoong/rss/response/23

Trackback URL : http://sinwoong.co.kr/tc/sinwoong/trackback/23

« Previous : 1 : 2 : 3 : 4 : 5 : ... 11 : Next »

달빛은 지금.. 파이팅파이팅
일도 사랑도 공부도
열심히 해보자 !!
남자O형사수자리경기도

Categories

  • ATOM 전체 (22)
    • ATOM 디바이스 드라이버 (1)
    • ATOM Win32, MFC (2)
    • ATOM C, C++, STL (12)
    • ATOM 라이브러리 (1)
    • ATOM 금융 (1)
    • ATOM DLP (2)
    • ATOM 보안 개발 (2)
    • ATOM 미분류 개발 (1)

- 최근 글

Recent Posts

  1. VC 9.0에서 Crypto++ Library를 이용하...
  2. C++ STL 프로그래밍(10) - 알고리즘 : (2)

- 최근 댓글

Recent Comments

- 최근 트랙백

Recent Trackbacks

Site Stats

Total hits:
3985
Today:
19
Yesterday:
46

EMB 통계

EMB가 0 개의 스팸을 막았습니다.
0 명이 RSS를 구독하고 있습니다.

Powered by TEXTCUBE. original designed by 1up of tiskin.