'Algorithm'에 해당되는 글 2건

  1. 2015.11.05 전자서명
  2. 2008.09.09 Sort.. algorithm

전자서명

UP! 2015. 11. 5. 11:00

전자서명

 

     내용

가)    개인 키와 함께 생성된 메시지 다이제스트

나)    서명

 

다)    서명 검증

 

 

     목적

가)    무결성

     데이터에 대해서 바뀌지 않았다는 것을 증명

     데이터와 메시지 다이제스트 두 개를 다 바꿀 수 있음

     다이제스트를 개인키로 서명하면 이것은 불가능해 짐

나)    인증

     개인 키의 소유자만이 데이터에 서명할 수 있음

     키가 안전하다면 사용자가 실제로 서명했다는 것을 확신할 수 있음

 

     활용

가)    계약서에 서명

     1999 7월부터 전자서명법이 발효됨

     기존의 일반 종이문서에 사용되는 인감이나 서명과 같은 법적 효력을 갖게 됨

나)    이메일 서명

     S/MIME PGP를 사용해서 개인 키로 이메일을 서명할 수 있음

다)    타임서버 생성

     타임 스탬프는 데이터에 시간과 함께 서명해서 어떤 특정 시간에 정보가 존재했는지를 증명

라)    서버 승인

     요청에 서명을 하면 사용자가 서버가 특정한 개인 키를 가졌는지 확인 가능

 

     RSA vs. DSA

가)    RSA

     서명을 검증하는데 빠름

 

나)    DSA(Digital Signature Algorithm)

     RSA에서 서명하는 것과 비슷하지만 암호화 기능은 없음

     서명을 만드는데 빠름

 

     자바의 전자 서명

가)    java.security.Signature

     getInstance() : 알고리즘 이름을 인자로 해서 객체의 인스턴스 획득

     initSign() : 개인 키를 인자로 서명

     initVerify() : 공개 키를 인자로 검증

     update() : 데이터를 전달하여 서명/검증을 수행

     sign() : 전자서명을 반환

     verify() : 전자서명의 유효성을 반환

 

     간단한 전자서명 예제

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.Signature;

import java.security.SignatureException;

 

import com.Ostermiller.util.Base64;

 

public class SignatureExample {

 

       public static void main(String[] args) throws Exception{

             //RSA 생성

             System.out.println("RSA 생성...");

             KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");

             kpg.initialize(1024);

             KeyPair keyPair = kpg.genKeyPair();

             System.out.println("RSA 생성 완료");

            

             // 서명할 데이터

             byte[] data = "i love you.".getBytes("UTF-8");

            

             // 서명을 위해 Signatrue 객체 생성 개인 키로 초기화

             Signature sig = Signature.getInstance("MD5WithRSA");

             sig.initSign(keyPair.getPrivate());

             sig.update(data);

             // 실제 서명

             byte[] signaturedBytes = sig.sign();

             System.out.println("전자서명된 데이타 : " + Base64.encode(signaturedBytes));

            

             // 전자서명 검증

             sig.initVerify(keyPair.getPublic());

             sig.update(data);

             boolean verified = false;

             try {

                    verified = sig.verify(signaturedBytes);

             } catch (SignatureException e) {

                    verified = false;

                    System.out.println("전자서명 형식에 문제가 발생하였습니다.");

                    e.printStackTrace();

             }

            

             if(verified)

                    System.out.println("전자서명 검증 성공");

             else

                    System.out.println("전자서명 검증 실패");

 

       }

 

}

 

     전자 서명의 한계

가)    검증을 위해서 공개 키가 필요

나)    공개 키의 소유자를 확신하기가 힘듬

다)    전자 인증서로 문제 해결

 

Posted by 으랏차
,

Sort.. algorithm

Algorithm 2008. 9. 9. 16:12
<5. 정렬 알고리즘(1) >

1) 개요

     * 정렬(sort) : 임의위 순서대로 배열하는 것
     *오름차순(ascending order)
     *내림차순(descending order)

     1] 정렬의 방법론
          * 파일(file) - 정렬대상, 정보의 단위인 레코드의 나열
          * 필드(field) - 각 레코드의 구체적 정보단위
          * 레코드(record)는 C에서 구조체로 표현, 필드는 구조체의 멤버!
          * 키(key) - 필드 중에서 비교의 대상인 것

     2] 정렬 알고리즘의 다양성
          * 간단 : 선택정렬, 삽입정렬, 거품정렬, 셀정렬
          * 복잡 : 퀵정렬, 기수정렬, 힙정렬, 병합정렬

          *내부정렬 (Internal sort) - 속도 빠름, 모든자료를 메인메모리로 옮겨 놓아야 하는 부담
          *외부정렬 (External sort) - 속도 느림, 자료가 메인메모리 차지안하므로 메모리 절약!

          *직접정렬 (Direct sort) - 메모리 절약 but 속도느림
          *간접정렬 (Indirect sort) - 메모리 소요, 실제 레코드 교환안하므로 속도 빠름

          * 삽입(Insertion) : ex) 삽입정렬
          * 교환(Exchange) : ex) 거품정렬, 퀵정렬, 기수교환정렬
          * 병합(Merging) :  ex) 병합정렬
          * 선택(Selection) : ex)선택정렬, 힙정렬
          * 세기(Counting) : ex) 분포수세기, 직접기수정렬

--------------------------------------------------------------------------------

2) 선택정렬 (Selection sort)

          (1) i=0;
          (2) i=n-1면 끝
          (3) i~n-1 중 최소값을 min에 저장
          (4) i항과 min항을 교환
          (5) i하나 증가 -> 2로~

     void select_sort (int a[], int n)
     {
          int min, minindex, i, j;

          for(i=0; i<n-1; i++)
          {
              minindex=i;
              min=a[i];
               for(j=i+1; j<n; j++)
               {
                    if(min>a[j])
                    {
                         min=a[j];
                         minindex=j;
                    }
               }
               a[minindex] = a[i];
               a[i] = min;
          }
     }

     # 배열 앞부분부터 차례로 정렬해 나간다.
     # 아직 정렬하지 않은 부분은 n의 변함이 없다.
     # 비교횟수 N^2/2정도, 교환횟수<=N (최악의 경우-역순일 때, 교환횟수=N)
     # 성능 O(N^2)
     # 안정성이 없다.
     # N<100에서 만족할 만한 속도~

--------------------------------------------------------------------------------

3) 삽입정렬 (Insertion sort)

     (1) i=1;
     (2) j=i;
     (3) a[j-1]>a[i], j>0인 동안
         a[j]=a[j-1]; j--;
     (4) a[j] = a[i];
     (5) i++, 2로~~ ( → i항 이하는 이미 정렬된 상태가 됨!!!)

     void insert_sort(int a[], int n)
     {
          int i, j, t;
          for(i=1; i<n; i++)
          {
               t=a[i];
               j=i;
               while(a[j-1]>t  && j>0)
               {
                    a[j]=a[j-1];
                    j--;
               }
               a[j]=t;
          }
     }

     # 삽입정렬은 입력자료에 민감
     # 이미 정렬된 배열일 경우 매우 빠름
     # 최악의 경우 : 역순!
     # 난수 배열인 경우 - 선택정렬보다 효율이 좋다
     # O(N^2)의 성능

--------------------------------------------------------------------------------

4) 거품정렬 (Bubble Sort)

     (1) i=0;
     (2) i=n-1되면 끝
     (3) j=1;
     (4) j=n-1면 7로
     (5) a[j-1]>a[j] 이면 두 값을 교환
     (6) j하나 증가 -> 4로
     (7) i증가, 2로!

     void bubble_sort(int a[], int n)
     {
          int i, j, t;
          for(i=0; i<n-1; i++)
         {
               for(j=1; j<n-1; j++)
               {
                    if(a[j-1]>a[j])
                    {
                         t=a[j-1];
                         a[j-1]=a[j];
                         a[j]=t;
                    }
               }
          }
     }

     # 최선의 경우 - 이미 정렬된 배열
     # 최악의 경우 - 역순!
    
--------------------------------------------------------------------------------

5) 쉘 정렬 ( Shell sort )
   -  h간격으로 떨어진 레코드를 삽입정렬 함

    (1)  h의 초기값을 구한다.
    (2)  h가 1보다 작으면 끝낸다
    (3) i=0;
    (4) i 가 h보다 크기가 같으면 7로 간다.
    (5) (h 간격+i)요소들에 대해서 삽입 정렬을 한다.
    (6) i를 하나 증가시키고 4로 간다.
    (7) h의 다음값을 구하고 2로 간다!

    void shell_sort (int a[], int n)
    {
        int i, j, k, h, v, j;
        for(h=0; i<h; i++)
        {
            for(j=i+h; j<n; j+=h)
            {
                v=a[j];
                k=j;

               while(k>h-1 && a[k-1]>v)
                {
                   a[k]=a[k-h];
                    k-=h;
                }
            a[k]=v;
        }
        }
    }

    # 안정성이 없다.
    # 입력자료의 형태에 상관없이 속도  good!!!
    # 최선의 경우 - 이미 정렬된것
    # 최악의 경우 - 난수 (하지만 그래도 빠른편!)
    # O(N(log N^2), O(N^1.25) 의 성능

--------------------------------------------------------------------------------

6) 분포수 세기 (Distribution counting)
        - 같은 키가 많이 있는 배열에 한해 적용할 수 있다.
        - 특정 키 값이 출현 하는 빈도를 저장하여 누적분포를 이용하여 간단하게 정렬

     (1) count[]배열을 O으로 초기화
     (2) a[] 배열의 키의 빈도를 계산하여 그 빈도를 count[]에 저장
     (3) count[]배열을 누적 분포로 변환
     (4) a[]배열을 뒤에서부터 읽어서 b[--count[a[i]]]에 저장

    coid dist_count (int a[], int n, int m)
    {
        int i; int *b, *count;
   
        b=(int*)malloc(sizeof(int)*n);
        count=(int*)malloc(sizeof(int)*(m+1));

        for(i=0; i<=m; i++) count[i]=0;
        for(i=0; i<n; i++) count[a[i]]++;
        for(i=2; i<=m; i++) count[i] = count[i-1] + count[i];
        for(i=n-1; i>=0; i--) b[--count[a[i]]] = a[i];
        for(i=0; i<n; i++) a[i]=b[i];
        free(b);
        free(count);
    }

--------------------------------------------------------------------------------


  


'Algorithm' 카테고리의 다른 글

CORBA, EJB, COM/DCOM  (0) 2008.12.05
ACID  (0) 2008.09.16
HDLC 프로토콜  (0) 2008.08.26
셀정렬  (1) 2008.08.23
삽입정렬  (0) 2008.08.23
Posted by 으랏차
,