클래스 상속

클래스를 선언할 때, 다른 클래스를 상속(inheritance)받아서 선언할 수 있습니다. 상속을 이용하면 기존 클래스의 속성과 메서드를 그대로 사용할 수 있으며, 필요한 기능만 추가하거나 수정할 수 있습니다. 다음과 같은 형식으로 상속을 사용할 수 있습니다.

 

class 기존클래스이름(상속받을클래스이름):
    추가할속성1 = 초기값1
    추가할속성2 = 초기값2
    def 추가할메서드1(self, 인자1, 인자2):
        코드
    def 추가할메서드2(self, 인자1, 인자2):
        코드

다형성

다형성(polymorphism)은 같은 메서드 이름을 사용하지만, 다른 기능을 수행하는 것을 말합니다. 파이썬에서는 메서드 오버라이딩(method overriding)과 메서드 오버로딩(method overloading)을 이용하여 다형성을 구현할 수 있습니다.

메서드 오버라이딩은 부모 클래스의 메서드를 자식 클래스에서 재정의하여 사용하는 것입니다. 다음과 같은 형식으로 메서드 오버라이딩을 할 수 있습니다.

 

class 부모클래스:
    def 메서드(self):
        코드

class 자식클래스(부모클래스):
    def 메서드(self):
        코드
 
 

메서드 오버로딩은 같은 이름을 가진 메서드를 인자의 개수나 타입에 따라 다르게 정의하여 사용하는 것입니다. 파이썬에서는 메서드 오버로딩을 지원하지 않으므로, 인자의 개수나 타입에 따라 다른 메서드 이름을 사용해야 합니다.

예제

다음은 계산기 클래스를 만드는 예제입니다.

 
 
class Calculator:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def add(self):
        return self.x + self.y
    def subtract(self):
        return self.x - self.y
    def multiply(self):
        return self.x * self.y
    def divide(self):
        return self.x / self.y

c = Calculator(10, 5)
print(c.add())
print(c.subtract())
print(c.multiply())
print(c.divide())
 

위 코드에서는 Calculator 클래스를 정의하고, 객체 c를 생성하여 다양한 메서드를 호출하여 계산 결과를 출력합니다.

결론

파이썬 클래스는 객체 지향 프로그래밍에서 가장 기본적인 개념 중 하나입니다. 클래스를 이용하여 객체를 생성하고, 속성과 메서드를 사용할 수 있습니다. 생성자와 소멸자를 이용하여 객체의 초기화와 메모리 관리를 수행할 수 있으며, 상속을 이용하여 기존 클래스를 확장할 수 있습니다. 다형성을 이용하여 같은 이름의 메서드를 다른 기능으로 사용할 수 있습니다. 클래스를 이용하여 프로그램을 작성하면 코드의 재사용성과 유지 보수성이 향상되며, 더욱 효율적인 프로그래밍이 가능해집니다.

 

클래스란 무엇인가?

클래스는 객체 지향 프로그래밍(Object-Oriented Programming)에서 가장 기본이 되는 개념 중 하나입니다. 클래스는 변수와 함수를 하나의 단위로 묶어서 다룰 수 있게 해줍니다. 객체(Object)는 이러한 클래스를 이용하여 만들어진 실체입니다. 즉, 클래스는 객체를 만들기 위한 설계도와 같은 역할을 합니다.

클래스의 선언

파이썬에서 클래스를 선언하는 방법은 다음과 같습니다.

class 클래스이름:
    변수1 = 초기값1
    변수2 = 초기값2
    def 메서드1(self, 인자1, 인자2):
        코드
    def 메서드2(self, 인자1, 인자2):
        코드

위와 같은 형식으로 클래스를 선언합니다. 클래스 이름은 대문자로 시작하는 것이 관례입니다.

객체 생성

클래스를 선언했다면, 이제 클래스를 이용하여 객체를 생성할 수 있습니다. 객체는 클래스의 인스턴스(instance)입니다. 다음과 같이 클래스를 이용하여 객체를 생성할 수 있습니다.

 

객체이름 = 클래스이름()

속성과 메서드

클래스 내에 선언된 변수를 속성(attribute)이라고 부릅니다. 클래스 내에 선언된 함수를 메서드(method)라고 부릅니다. 클래스를 이용하여 생성된 객체는 이러한 속성과 메서드를 사용할 수 있습니다. 메서드는 객체의 상태를 변경할 수 있습니다.

생성자와 소멸자

클래스를 이용하여 객체를 생성할 때, 객체의 속성을 초기화해주어야 합니다. 이러한 초기화를 수행하는 함수를 생성자(constructor)라고 부릅니다. 생성자는 클래스가 객체화될 때 자동으로 호출됩니다.

파이썬에서는 다음과 같은 형식으로 생성자를 정의합니다.

 
def __init__(self, 인자1, 인자2):
    self.속성1 = 인자1
    self.속성2 = 인자2

소멸자(destructor)는 객체가 메모리에서 제거될 때 자동으로 호출됩니다. 파이썬에서는 다음과 같은 형식으로 소멸자를 정의합니다.

 
def __del__(self):
    코드

다음장은 클래스와 더불어 상속의 개념과 활용 방법에 대해서 알아보겠습니다.

 

다음장

https://cosmosproject2015.tistory.com/498

 

 

1. JDK 설치하기

안드로이드 스튜디오를 설치하기 전에, 먼저 JDK(Java Development Kit)를 설치해야 합니다. 다음 명령어를 사용하여 JDK를 설치합니다.

sudo apt-get update sudo apt-get install openjdk-8-jdk
 

2. 안드로이드 스튜디오 다운로드 및 설치하기

안드로이드 스튜디오를 다운로드하고 설치하는 방법은 총 세가지 입니다.

 

1) 첫번째 방법 - 웹에서 다운받아 설치 하기

  1. 안드로이드 스튜디오 다운로드 페이지(https://developer.android.com/studio) "Download Android Studio" 버튼을 클릭하여 다운로드합니다.
  2. 다운로드가 완료되면, 다운로드한 파일을 추출합니다.
  3. 추출된 폴더에서 "bin" 폴더로 이동하여 "studio.sh" 파일을 실행합니다.
해당 페이지를 방문하여 초록색 버튼을 누르면 된다.
cd ~/Downloads 
tar -xvzf android-studio-ide-xxx.xxxxxxx-linux.tar.gz 
cd android-studio/bin 
./studio.sh

 

2) 두번째 방법 - SNAPCRAFT 통한 이미징 패키지로써 설치 하기

 

snap이 깔려 있다면 이 방법을 사용 하는 것도 나쁘지 않습니다.

 

sudo snap install android-studio --classic

 

3) 세번째 방법 - PPA 등록을 통한 패키지 설치

 

apt-get ppa 등록 패키징을 활용함 으로써 추후 업데이트를 빠르게 적용 할수 있는 장점이 있습니다.

 

sudo apt-add-repository ppa:maarten-fonville/android-studio
sudo apt-get update 
sudo apt-get install android-studio

 

3. 안드로이드 스튜디오 설정하기

안드로이드 스튜디오를 실행하면, 초기 설정 화면이 나타납니다. 다음 설정을 선택하여 진행합니다.

  1. "Standard"를 선택하여 표준 설치를 진행합니다.
  2. "SDK Components Setup"에서 필요한 SDK Component를 선택하고 "Next"를 클릭합니다.
  3. "Verify Settings"에서 설정을 확인하고 "Finish"를 클릭합니다.

안드로이드 스튜디오란?

안드로이드 스튜디오는 안드로이드 애플리케이션 개발을 위한 통합 개발 환경(IDE)입니다. 이는 Google에서 개발하였으며, Java, Kotlin 등의 언어를 지원합니다.

안드로이드 스튜디오는 안드로이드 애플리케이션 개발을 위한 다양한 기능을 제공합니다. 예를 들어, 레이아웃 디자인, 코드 편집, 디버깅, 빌드 및 배포 등의 기능이 있습니다.

안드로이드 스튜디오 개발 환경 설정

안드로이드 스튜디오를 사용하기 위해서는 먼저 개발 환경을 설정해야 합니다. 안드로이드 스튜디오는 Windows, macOS, Linux 등 다양한 운영체제에서 사용할 수 있습니다.

개발 환경 설정을 위해서는 다음과 같은 단계를 따릅니다.

  1. 안드로이드 스튜디오 다운로드 및 설치
  2. JDK(Java Development Kit) 설치
  3. 안드로이드 SDK(소프트웨어 개발 키트) 설치

이제 안드로이드 스튜디오를 시작할 수 있습니다.

 

현재 버전의 안드로이드 스튜디오 개발 환경의 모습

안드로이드 스튜디오 프로젝트 생성

안드로이드 스튜디오에서 프로젝트를 생성하는 방법은 다음과 같습니다.

  1. 안드로이드 스튜디오 실행
  2. "Create New Project" 선택
  3. 애플리케이션 이름, 패키지 이름, 프로젝트 위치 등 필요한 정보 입력
  4. "Minimum SDK" 선택
  5. "Empty Activity" 선택

이제 안드로이드 스튜디오에서 새로운 프로젝트가 생성되었습니다.

안드로이드 스튜디오 레이아웃 디자인

안드로이드 스튜디오에서 레이아웃을 디자인하는 방법은 다음과 같습니다.

  1. "res" 폴더에서 "layout" 폴더 선택
  2. "activity_main.xml" 파일 선택
  3. 레이아웃 디자인을 위한 "Design" 탭 선택
  4. 레이아웃을 구성하는 위젯들을 추가

안드로이드 스튜디오 코드 편집

안드로이드 스튜디오에서 코드를 편집하는 방법은 다음과 같습니다.

  1. "app" 폴더에서 "java" 폴더 선택
  2. "MainActivity.java" 파일 선택
  3. 코드 편집을 위한 "Code" 탭 선택
  4. 코드를 입력하거나 수정

안드로이드 스튜디오는 코드 작성을 도와주는 다양한 기능을 제공합니다. 예를 들어, 자동완성, 코드 검사, 디버깅 등의 기능이 있습니다.

안드로이드 스튜디오 디버깅

안드로이드 애플리케이션에서 발생하는 오류를 해결하기 위해서는 디버깅을 해야 합니다. 안드로이드 스튜디오에서 디버깅하는 방법은 다음과 같습니다.

  1. 코드 편집 탭에서 디버그 모드로 변경
  2. 브레이크포인트(breakpoint) 설정
  3. 디버그 시작
  4. 애플리케이션 실행 중에 브레이크포인트에서 멈춤
  5. 변수 값, 메서드 호출 등을 확인하고 수정

안드로이드 스튜디오는 디버깅을 위한 다양한 기능을 제공합니다. 예를 들어, 로그 출력, 스택 추적, 변수 모니터링 등의 기능이 있습니다.

안드로이드 스튜디오 빌드 및 배포

안드로이드 애플리케이션을 빌드하고 배포하는 방법은 다음과 같습니다.

  1. "Build" 메뉴에서 "Build APK" 선택
  2. 빌드가 완료되면 "app" 폴더에서 "build" 폴더 선택
  3. "outputs" 폴더에서 생성된 APK 파일 선택
  4. 안드로이드 기기에 APK 파일을 설치

안드로이드 스튜디오는 빌드 및 배포를 위한 다양한 기능을 제공합니다. 예를 들어, 다양한 디바이스에 대한 빌드, 서명, 앱 스토어 배포 등의 기능이 있습니다.

다음 장 에서 부터는 실제 리눅스 우분투 운영체제에 안드로이드 개발 환경을 설치해 보도록 합니다

 

 

1. 자바에서 상속(Inheritance)이란?

 

상속은 객체 지향 프로그래밍에서 매우 중요한 개념 중 하나입니다. 상속이란, 이미 존재하는 클래스에서 필요한 부분을 그대로 물려받아 새로운 클래스를 만드는 것을 말합니다. 이렇게 상속받은 클래스는 원래의 클래스의 모든 멤버를 가지고 있으면서, 추가로 필요한 멤버를 가질 수 있습니다.

 

상속의 대표적인 예시로는 '동물' 클래스와 '개', '고양이' 클래스가 있습니다. '개'와 '고양이' 클래스는 '동물' 클래스에서 필요한 부분을 물려받아 새로운 클래스를 만든 것입니다. 이렇게 만들어진 '개'와 '고양이' 클래스는 '동물' 클래스의 모든 멤버를 가지면서, 추가로 필요한 멤버를 가질 수 있습니다.

 

2. 자바에서 상속의 구현

 

자바에서 상속을 구현하는 방법은 매우 간단합니다. 상속받고자 하는 클래스의 이름 뒤에 'extends' 키워드를 붙이고, 상속하고자 하

는 클래스의 이름을 적어주면 됩니다. 예를 들어, '개' 클래스가 '동물' 클래스를 상속받는다면, 다음과 같이 작성할 수 있습니다.

 
-예제 코드-
 
class 동물 {
  String 이름;
  int 나이;
  
  void 소리내기() {
    System.out.println("소리를 내다.");
  }
}

class 개 extends 동물 {
  void 짖기() {
    System.out.println("멍멍!");
  }
}

위의 코드에서 '개' 클래스는 '동물' 클래스를 상속받았습니다. 따라서 '개' 클래스는 '동물' 클래스의 모든 멤버를 가지고 있으며, '동물' 클래스에서 정의한 '소리내기' 메서드를 그대로 사용할 수 있습니다. 또한, '개' 클래스에는 '짖기' 메서드가 추가로 정의되어 있습니다.

 

3. 상속의 장점

 

상속의 가장 큰 장점은 코드의 재사용성입니다. 이미 만들어진 클래스를 상속받아 필요한 부분만 추가하여 새로운 클래스를 만들기 때문에 코드를 반복해서 작성할 필요가 없습니다. 또한, 기존 클래스의 수정 없이 새로운 기능을 추가할 수 있습니다.

또한, 상속은 객체 지향 프로그래밍의 다형성(Polymorphism) 개념을 가지고 있습니다.

 

먼저 라이브러리를 호출하고 기본적인 변수를 설정 한다.

(예 : json 파일이 'file.json' 일 경우)

import json

with statement with open('file.json') as json_file: 
	json_dict = json.load(json_file)

 

가져온 json 데이타의 특정 숫자 데이타 가져오기 

json_num = json_data["json_num"]
	print(str(json_num)) 

 

전체 코드 ( ALL code )

 

import json

with statement with open('file.json') as json_file: 
	json_dict = json.load(json_file)

json_num = json_dict["json_num"]
    print(str(json_num)) 


먼저 귀하의 리눅스 우분투에 java가 올바르게 설치 되었는지 확인 하였다면 (

 

이제 본격적으로 리눅스 터미널에서 java 파일을 만들고 컴파일 해보자.




    ## 먼저 간단히 텍스트 편집기를 이용하여 텍스트 출력 형태의 간단한 java 소스 코드 파일을 만들어 보자.

    $ gedit hello_world.java
   
        ! 만일 gedit 가 설치 되어 있지 않다면
       
            $ sudo apt install gedit
       
        ! 혹은

            $ nano hello_world.java
             (nano: 나노 에디터)   

 

hello_world.java

class hello_world {
    public static void main( String[] args ) {
        System.out.println( "Hello world" );
    }
}


 

 

 ## 만든 java 파일을 컴파일 한다.

    $ javac hello_world.java
      (javac: java 컴파일 명령)   

    ## 컴파일이 정상적으로 완료 되었다면 해당 디렉터리에 hello_world.class 클래스 파일을 생성 되었을 것이다.
       그것을 실행토록 해보자.


    $ java hello_world
        ( 파일명.class를 붙이지 않는다.)

    ## "Hello world"가 뜨고 리턴 하였다면 컴파일과 실행에 성공한 것이다.

 



 

 

 

 

 

 



리눅스를 활용하게 되면 오픈소스와 레파시토리로 인하여 프로그래밍과 정말 가까워 진다.

그렇기에 자바 및 파이썬 그리고 c 언어 까지 컴파일 및 실행이 무척이나 빠르다.

또 그러므로 BASH 스크립트를 이용하여 이에 대한 과정을 2차 프로그래밍 하여 소스 패키지로써 재배포가 가능한 것이다.

하지만 물론 기초적으로 처음 설치한 리눅스에 java 클라이언트가 설치되어 있을지는 미지수 이다.

그렇기 때문에 먼저 java가 설치 되어 있는지 확인이 필요하다.

    ## 터미널을 열고서 java를 실행해 본다.

    $ java

다음과 같은 설명문이 나오면 java가 설치 되어 있음을 확인한 것이다.



하지만 이와 같은 화면은 oracle-java 가 아닌 openjdk 이다.

본 필자도 마찬가지고 인터넷 에서의 기초 전문가들도 대부분 openjdk 보다는 oracle-java를 설치 하기를 권고 하고 있다.

그렇다면 설치되어 있는 java 클라이언트가 openjdk 인지 아니면 oracle-java 인지 확인이 필요할 것이다.

    ## java 클라이언트의 특성과 버전을 확인한다.

    $ java -version

    ## 만일 다음과 같은 화면이 나온다면 openjdk가 설치되어 있는 것이다.

    openjdk version "9-internal"
    OpenJDK Runtime Environment (build 9-internal+0-2016-04-14-195246.buildd.src)
    OpenJDK 64-Bit Server VM (build 9-internal+0-2016-04-14-195246.buildd.src, mixed mode)

    ## 만일 다음과 같은 화면이 나온다면 oracle-java 가 설치되어 있는 것이다.

    java version "9-ea"
    Java(TM) SE Runtime Environment (build 9-ea+126)
    Java HotSpot(TM) 64-Bit Server VM (build 9-ea+126, mixed mode)
 

만약 openjdk가 설치되어 있다면 oracle-java로 클라이언트를 바꾸어 보자.
이는 다른 운영체제 처럼 굳이 Oracle 홈페이지를 방문할 필요 없이 '레파시토리'를 등록하여 자유롭게 다운받아 사용할 수 있을 것이다.

openjdk를 삭제하고 레파시토리를 등록한 다음 설치 아카이브정보를 업데이트 하고 oracle-java9을 설치 하도록 하자.


 

 user@user~$

sudo apt-get purge openjdk*   
sudo apt-add-repository ppa:webupd8team/java   
sudo apt update   
sudo apt install oracle-java9-installer   
java -version


Loading Captcha...
If it doesn't load, please disable Adblock!

체크시 자동으로 본 사이트에 대한 자원 활용(채굴) 지원이 이루어 지고 '복사 버튼' 이 활성화 됩니다.


   
   

다음 페이지 - 리눅스 우분투 터미널에서 본격적으로 java를 컴파일 및 실행하기 (예제 파일 포함) 바로가기

   

도움이 되셨다면 '♡' 버튼을 꼭눌러 주시면 감사 하겠습니다.


그리고 글에 부족한 점이 있거나 틀린 점, 더 궁금한 부분이 있는 것 같다면 꼭 댓글로 알려 주시 감사 하겠습니다.

         


Loading Captcha...
If it doesn't load, please disable Adblock!

별 다른 절차 없이 바로 위의 한 번의 체크 만으로  기기의 성능을 기반으로 하여 본 블로그에 아주 잠깐 채굴 지원 하실 수 있습니다.


비트코인 - BTC 지원 :


리플 - XRP 지원 :




한가지 재미있는 실험적 발상을 떠올렸다. 

로또 담청 번호를 미리 정해 놓고 과연 자동을 계속 뽑으면 과연 몇번만에 당첨이 될까(전부 맞는 집합이 이루어 질까)? 라는 발상이다.

이 포스트는 로또에 관심이 있고 또 당첨의 꿈을 가지고 살고 있는 자칭 '로또 매니아'라면 필히 훑어 볼 것을 권하는 바이다.

아~ 물론 프로그래밍과 파이썬 언어에 대해 전혀 모르고 계셔도 무관하다. 

포스팅 마지막 부분에는 그 결과가 공개되니까 말이다.

물론 로또의 확률은 이미 8145060분의 1일 이라는 사실을 이미 알고 있다.

하지만 실제 각 게임 당 랜덤 출현(완전 자동)으로 몇번만에 1등 당첨이 이루어 지는 가는 매번 틀릴 것이다.

그렇기에 실제 실험에서 몇 번만에 과연 당첨이 되는가를 테스트 


해당 프로그램은 순 100% 'bash 쉘 스크립트'로 만들어 졌으며 물론 모든 경우의 집합을 만드는 것은 아닌 유력 번호들을 가장 많이 배열하여 그 중 컴퓨터가 RANDOM 모듈로 번호들을 뽑아 내는 방식 이다. 물론 이런 방식으로 지정한 확률 높은 번호가 출현하기가 유리하긴 하다.

또 이번 실험을 bash보다 파이썬을 택한 이유는 파이썬이 RANDOM 함수를 사용하는데 있어서 능력이 훨씬 더 뛰어 나기 때문 이기도 하다. 그로인해 glotto-k 다음 배포버전도 파이썬으로 다시 재개발할 예정 이다.

본론으로 파이썬으로 로또의 랜덤(자동) 확률을 테스트 하는 프로그램을 만들어 보도록 하자.

  Source_File name : copy_to_clipboard.html     |     Type : java_script html    |                      |           


# -*- coding: utf-8 -*- 
import random
import time


s = time.time()	# 시간을 측정하기 위한 변수 생성


def mtask(): 	# 1~45 숫자 집합을 자동으로 만들고 랩덤 당첨 집합 변수를 만드는 함수를 생성
	n = 1
	l = [1]

	for i in xrange(44):
	
		n = n + 1 
		l = l + [n]
	a = random.choice(l)

	l.remove(a) # 중복 출현 방지를 위해 출현 번호를 집합에서 제외

	b = random.choice(l)

	l.remove(b)
	c = random.choice(l)
	
	l.remove(c)
	d = random.choice(l)

	l.remove(d)
	e = random.choice(l)
	l.remove(e)
	f = random.choice(l)
	l.remove(f)
	global ans
	ans = [a, b, c, d, e, f] # 번호 집합 생성
	ans.sort()	# 숫자 크기로 재나열

	
mtask()
answer = ans	# 처음 mtask함수로 만들어진 전역변수 ans를 고정 당첨 번호로 지정한다.
print "시작....고정 당첨번호 집합은", answer , "입니다."
global tan
tan = [0]
line=0
while answer != tan:	# 고정번호집합과 새로 생성된 집합이 나올때 까지 새로운 집합을 만드는 반복문을 실행한다. 
	line=line+1
	
	mtask()
	tan = ans
	print line,"번째 값은", tan ,"입니다."
e=time.time()

et = e - s	# 시간 측정 변수 생성 



print "\n종료 되었습니다.\n고정 번호은",answer,"이며,\n 마찬가지 겟팅 번호는",tan,"이며 총",line,"번 수행 하였습니다.\n총 걸린 시간은",et,"초 입니다.\n그리고 이번 게임의 당첨 확률은 1/", line, " 입니다."


Loading Captcha...
If it doesn't load, please disable Adblock!

체크시 자동으로 본 사이트에 대한 자원 활용(채굴) 지원이 이루어 지고 클립보드 복사 버튼이 활성화 됩니다.



-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>

// 소스 파일을 만들었으면 실행해 본다.


user@user-test:~$ python lot.py

.................

10646537 번째 값은 [14, 18, 22, 23, 31, 35] 입니다.
10646538 번째 값은 [1, 3, 14, 24, 31, 35] 입니다.
10646539 번째 값은 [10, 11, 25, 29, 30, 36] 입니다.
10646540 번째 값은 [1, 19, 23, 25, 29, 34] 입니다.
10646541 번째 값은 [11, 20, 29, 31, 39, 44] 입니다.
10646542 번째 값은 [2, 13, 16, 33, 37, 45] 입니다.
10646543 번째 값은 [5, 18, 23, 29, 33, 34] 입니다.
10646544 번째 값은 [8, 10, 15, 18, 33, 43] 입니다.
10646545 번째 값은 [4, 9, 12, 14, 15, 23] 입니다.
10646546 번째 값은 [26, 29, 31, 34, 37, 43] 입니다.
10646547 번째 값은 [15, 18, 24, 33, 34, 38] 입니다.
10646548 번째 값은 [4, 11, 18, 19, 27, 38] 입니다.
10646549 번째 값은 [4, 5, 7, 17, 32, 38] 입니다.
10646550 번째 값은 [6, 7, 21, 27, 29, 44] 입니다.

종료 되었습니다.
고정 번호은 [6, 7, 21, 27, 29, 44] 이며,
 마찬가지 겟팅 번호는 [6, 7, 21, 27, 29, 44] 이며 총 10646550 번 수행 하였습니다.
총 걸린 시간은 509.503417015 초 입니다.
그리고 이번 게임의 당첨 확률은 1/ 10646550  입니다.


-> 프로그램을 실행하면 초기 배정된 번호집합을 똑같이 맞힐대 까지 각 프로세스 실행때 마다 평균 수백만번을 대략 평균 3~5분 정도의 시간으로 연산 출력해 낸다. 



그렇다.

실제 실험을 통해서도 각 게임당 계속 해봐도 평균 수백만번의 경우에 완전일치(1등)이 나오는 것을 볼 수가 있다.

즉 실제 로또와 비교한다면 한 주에 수백만개 정도의 게임(자동)을 사야 1등에 안정적으로 담청 될 수 있다는 것이다.

이 사실은 로또 매니아들에게 가히 절망적임을 안겨 줄 수는 있지만 그렇다고 해서 크게 실망할 필요는 없다.

로또는 이와 같은 절망을 극복하기 위한 방책으로 반자동 (몇개만 표시 와 자동 표시)이나 다섯개임 (한종이)에 여러방식의 게임을 섞는 방식도 있기 때문이다.
그리고 확률 분석으로 높은 확률의 번호를 찍어 당첨 확률을 높이는 방법도 있을 것이다.

확률 높은 번호는 존재 하며 찾아 낼 수 있다.

왜냐하면 앞서 실험에서도 봤듯이 같은 번호 집합 패턴이 똑같이 나오려면 평균 수백만번이 필요하기 때문이다.

그렇다. 역발상 이다. 그렇기에 실험에서 얻어낸 해답으로 역발상으로 말미앎아 오히려 확률 높은 번호가 충분이 추론될수 있음을 역설적으로 증명한 것이나 마찬가지 인 셈이다.

다음 실험에서는 좀 더 수준 높은 방식으로 실제 당첨 번호를 가지고 그 회차에 가지고 있는 확률을 적용 함으로써 과연 몇번에 맞추는 효과를 가지는 지를 테스트 해 보고 그로 말미앎아 새로운 glotto-k를 파이썬 언어로 개발할 계획이다.
   

도움이 되셨다면 '♡' 버튼을 꼭눌러 주시면 감사 하겠습니다.


그리고 글에 부족한 점이 있거나 틀린 점, 더 궁금한 부분이 있는 것 같다면 꼭 댓글로 알려 주시 감사 하겠습니다.

         


Loading Captcha...
If it doesn't load, please disable Adblock!

별 다른 절차 없이 위를 체크 하시면  본 블로그에 아주 잠시 동안 채굴 지원 하실 수 있습니다.


비트코인 - BTC 지원 :


리플 - XRP 지원 :

리눅스에서 C언어를 활용해 OPENGL을 구현하는 것은 윈도우즈에서와 별반 차이가 없다. 

오히려 소프트웨어 레파시토리에서 관련 dev패키지를 바로 설치 할 수 있으니 개발에 더욱 그 편의성을 앞당길수가 있다. 

다른 것이 있다면 헤더 라이브러리 임포팅 할때에 opengl 헤더인 'glut.h' 을 GL/glut로 잡아주어야 한다는 점이고 터미널 컴파일에서의 신경을 조금 쓰는 것 뿐이다. 

가장 먼저 해야 할 일은 opengl 헤더 설치를 위 개발 패키지를 다운 받는 것이다.

다음과 같은 명령으로 기본 레파시토리에서 간단히 다운 받을수 있다.

-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>

// opengl를 설계 및 컴파일을 위한 라이브러리를 설치 한다.


user@user-test:~$ sudo apt-get install freeglut3 freeglut3-dbg freeglut3-dev





설치가 되었다면 본격적인 openg 구현을 위한 c 코딩에 들어가 보도록 하자. 



  Source_File name : glsample.c     |     Type : C    |                        |           


#include <GL/glut.h> // opengl 라이브러리를 임포트 한다.

void play_display() // 생성할 opengl source를 설계한다. (실제 도형 및 그림 설계 )
{


 glClear(GL_COLOR_BUFFER_BIT);
 glBegin(GL_TRIANGLES);
   
 glVertex2f(0.5, 0.5);
 glVertex2f(-0.5, 0.5);
 glVertex2f(0.5, -0.5);
 glEnd();
glFlush();
}
void wincolor() { // 생성될 glut 디스플레이의 배경색을 결정할 함수를 설계 한다.
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
}

int main(int argc, char** argv) {
    glutInit(&argc, argv); // glut 시작시 가장 먼저 포함되어야 할 중요한 함수 선언 
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); // 생성될 glut 디스플레이의 모드 
    glutInitWindowPosition(5,5); // 생성될 glut 디스플레이의 위치
    glutInitWindowSize(700, 700); // 생성될 glut 디스플레이의 사이즈
    glutCreateWindow("sample"); // 생성될 glut 디스플레이의 이름 선언

    wincolor(); // 설계한 배경색 함수를 호출 한다.
    glutDisplayFunc(play_display); // 설계한 opengl source를 호출한다.
    glutMainLoop(); // main함수의 전체 glut 소스 명령을 실행한다.

    return 0;
}


Loading Captcha...
If it doesn't load, please disable Adblock!

체크시 자동으로 본 사이트에 대한 자원 활용(채굴) 지원이 이루어 지고 '소스코드 편집 복사 버튼' 이 활성화 됩니다.



소스를 설계 했다면 이제 컴파일을 해보도록 하자.


// 코딩한 파일을 'g++' 명령으로 컴파일 한다.


 user@user~$

g++ glsample.c -lGL -lGLU  -lglut -o glsample


Loading Captcha...
If it doesn't load, please disable Adblock!

체크시 자동으로 본 사이트에 대한 자원 활용(채굴) 지원이 이루어 지고 '복사 버튼' 이 활성화 됩니다.




// 컴파일한 파일을 실행 한다.


 user@user~$

./glsample


Loading Captcha...
If it doesn't load, please disable Adblock!

체크시 자동으로 본 사이트에 대한 자원 활용(채굴) 지원이 이루어 지고 '복사 버튼' 이 활성화 됩니다.



그러면 설계한 대로 다음과 같은 화면을 볼 수가 있다.

도움이 되셨다면 '♡' 버튼을 꼭눌러 주시면 감사 하겠습니다.


그리고 글에 부족한 점이 있거나 틀린 점, 더 궁금한 부분이 있는 것 같다면 꼭 댓글로 알려 주시 감사 하겠습니다.

         


Loading Captcha...
If it doesn't load, please disable Adblock!

별 다른 절차 없이 위의 한 번의 체크 만으로 기기의 성능을 기반으로 하여 본 블로그에 아주 잠시 동안 지원 하실 수 있습니다.


비트코인 - BTC 지원 :


리플 - XRP 지원 :



인터넷에서 JAVA 프로그래밍에 대한 예제를 찾아서 막상 컴파일 해 보면 안되는 경우가 허다 할 것이다.

그 요인은 전체적으로 두 가지 요인으로 볼 수 있는데

하나는 소스 구성이 이전 버전으로 구성 되어 있는 것이며

또 하나는 파일의 인코딩이 다르기 때문이다.

먼저 인코딩을 설명 한다면 JAVAC(JAVA 컴파일러)는 기본적으로 UTF-8을 우선적으로 지원하기 때문이다.

만일, 해당 소스 파일이 'EUC-KR'로 되어 있다면 JAVAC가 인식하지 못하면서 컴파일에 실패 한다.

먼저 만약 소스 코드 구성은 최신 버전에 맞지만 인코딩만 다를 경우를 컴파일을 시도해 보자.


< 해당 'a.java' 소스 파일이 'EUC-KR'인코딩일 경우 >

$ JAVAC -encoding euc-kr a.java
        (euc-kr : 인코딩 지정)

< 컴파일에 성공했는지 확인해 본다. >

$ ls

a.java a.class




< 이번에는 이전 버전의 소스코드와 인코딩이 다른 경우 두가지를 모두 포함하고 있는 경우를 해결해 볼 것이다. >


그러는 이유는 이 방법에는 순서가 있기 때문이다.


물론 프로그래머 스스로가 소스를 수정하여 해결할수도 있겠지만 javac는 이전 버전의 소스 형식도 잡아주는 기능이 있기 때문에 그것을 최대한 활용 하는 것이 훨씬 더 수월 할 것이다.


그리고 이번에는 본 필자가 소스 파일을 제공해 줄 것이다.


a.java


< 위의 파일을 직접 다운 받거나 본 블로그에서 제공하는 예제 파일을 터미널에서 wget을 활용하여 원하는 폴더에  다운로드 한다. >

$ wget http://cosmosproject2015.tistory.com/attachment/cfile21.uf@246C454257AD51422E2D22.java -O a.java


// 받은 파일을 a.java로 변경한다.

< 다운로드 되었는지 확인한다.>


$ ls


a.java


< 먼저 해당 java 파일에 대한 타겟 버전을 설정한다. >

$ javac -target 1.4 a.java
       (타겟 옵션 : 버전 1.4)

javac: target release 1.4 conflicts with default source release 1.9

    * 현재 버전 1.9에 의해 1.4 문제를 타겟 배포 했다는 문구가 출력 된다.

< 이제 인코딩과 컴파일을 같이 실행한다. > >>

$ javac -encoding euc-kr a.java

< 실행해 본다. > >

$ java a


Hello World
성공했습니다!


* 위와 같이 나온다면 성공한 것이다.


도움이 되셨다면 '♡' 버튼을 꼭눌러 주시면 감사 하겠습니다.


그리고 글에 부족한 점이 있거나 틀린 점, 더 궁금한 부분이 있는 것 같다면 꼭 댓글로 알려 주시 감사 하겠습니다.

         




필자는 예전에 부저장치를 이용한 라즈베리파이로 구동 하는 '부저 피아노' 를 연습용 프로그래밍 개발로 내놓은 적이 있다. [바로가기]

당시 포스팅의 목적은 라즈베리파이의 유용성과 파이썬 프로그래밍의 유용성을 알리기 위함이 목적 이었다면 이번 포스팅은 파이썬 그 자체만의 유용성을 알리고자 하는 목적이 될 것이다.

이번 프로그래밍 가이드는 순수히 파이썬만 활용하고 gui 디스플레이 기반의 유명한 교육용 게임 제작 모듈인 'pygame' 을 적극적으로 활용할 것이다.

그리고 해당 모듈을 활용하기 위해서는 모듈을 다운받아 파일 시스템에 적용 시켜야 한다.

pygame 모듈을 활용하여 키눌림과 키올라감을 감지하는 이벤트 처리와 동시에 음악을 재생하는 모듈도 pygame으로 활용하기로 한다. 

리눅스 우분투라면 간단히

-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>



user@user-test:~$ sudo apt-get install python-pygame


-> 로써 모듈을 바로 설치하여 프로그래밍 할 수 있다.




혹은 http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame 에 접속하여 자신의 시스템에 맞는 모듈을 직접 다운받아

-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>


user@user-test:~$ sudo pip install <파일명.whl>


-> 로써 모듈을 설치 한다.




다음으로는 소리를 재생할 음악파일을 다운 받는다. 

음악소스 파일은 망태기님 블로그의 음원 http://blog.daum.net/_blog/BlogTypeView.do?blogid=0S5D7&articleno=854 을 그대로 활용한다.



-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>

// 터미널에서 바로 파일명을 지정하여 다운받자.


user@user-test:~$ wget -O 1.mp3 https://t1.daumcdn.net/cfile/blog/186170454F44FE8911

user@user-test:~$ wget -O 2.mp3 https://t1.daumcdn.net/cfile/blog/156322454F44FE8A0F

user@user-test:~$ wget -O 3.mp3 https://t1.daumcdn.net/cfile/blog/1765AC454F44FE8B0C

user@user-test:~$ wget -O 4.mp3 https://t1.daumcdn.net/cfile/blog/116018454F44FE8C13

user@user-test:~$ wget -O 5.mp3 https://t1.daumcdn.net/cfile/blog/14605A454F44FE8D12

user@user-test:~$ wget -O 6.mp3 https://t1.daumcdn.net/cfile/blog/12586D454F44FE8E18

user@user-test:~$ wget -O 7.mp3 https://t1.daumcdn.net/cfile/blog/1658CC454F44FE8F1C

user@user-test:~$ wget -O 8.mp3 https://t1.daumcdn.net/cfile/blog/125876454F44FE901E



소스코드는 다음과 같다.

              Source_File name : py_piano.py           |           Type : python             |                        |           


# -*- coding:utf-8 -*-
import pygame, time

from pygame.locals import *
pygame.init()	#pygame 라이브러리를 로드 한다.

display_screen = pygame.display.set_mode((815, 85)) # 디스플레이 창 크기 설정

pygame.display.set_caption('MINI PYTHON PIANO')	# 디스플레이 이름

pygame.mouse.set_visible(1)	# 마우스 커서 활성화

white = (255, 255, 255)	# 색 지정

black = (0, 0, 0)

display_font = pygame.font.Font('/usr/share/fonts/truetype/nanum/NanumBarunGothic.ttf', 32) # 폰트 지정

text = (u"키보드 1~8까지 꾸욱 눌러 보세요. \n Esc키를 누르면 종료 됩니다.")	# 유니코드 인코딩으로 텍스트 설계

display_text = display_font.render(text, True, black, white)	# 설게한 텍스트를 랜더링 한다.

display_text_vis = display_text.get_rect()	# 디스플레이에 표시

display_text_vis.center = (340, 34)	# # 디스플레이에 표시되는 위치 설정

def mp(file):	# 소리 파일을 불러 오는 파일을 불러오는 함수
	pygame.mixer.music.load(file)
	
while True:

	display_screen.fill(white)	# 디스플레이의 배경색 지정
	
	display_screen.blit(display_text, display_text_vis)	# 디스플레이에 텍스트 표시
	
	pygame.display.update()	# 디스플레이를 계속 업데이트 한다.

	for event in pygame.event.get():	# 이벤트 시작
      
      
		if (event.type == KEYDOWN):	# 키를 눌렀을 경우 mp함수가 음악 파일을 불러오고 pygame모듈이 재생
			if (event.key == pygame.K_1):

				mp("1.mp3")
				pygame.mixer.music.play()
 
      
		if (event.type == KEYDOWN):
     			if (event.key == pygame.K_2):

				mp("2.mp3")
				pygame.mixer.music.play()
     
		if (event.type == KEYDOWN):
     			if (event.key == pygame.K_3):

				mp("3.mp3")
				pygame.mixer.music.play()
			
		if (event.type == KEYDOWN):
     			if (event.key == pygame.K_4):

				mp("4.mp3")
				pygame.mixer.music.play()
			
		if (event.type == KEYDOWN):
     			if (event.key == pygame.K_5):

				mp("5.mp3")
				pygame.mixer.music.play()
			
		if (event.type == KEYDOWN):
     			if (event.key == pygame.K_6):

				mp("6.mp3")
				pygame.mixer.music.play()
		if (event.type == KEYDOWN):
     			if (event.key == pygame.K_7):

				mp("7.mp3")
				pygame.mixer.music.play()
		if (event.type == KEYDOWN):
     			if (event.key == pygame.K_8):

				mp("8.mp3")
				pygame.mixer.music.play()
				
		if (event.type == KEYUP):	# 키가 올라갔을때(땠을 때) 재생을 중단 시킴


     			pygame.mixer.music.stop()
      
      
		if (event.type == KEYUP):	# esc 키를 누르고 땠을때 종료 실행
      			if (event.key == pygame.K_ESCAPE):

      				pygame.quit()
	
		if event.type == QUIT:	# 창을 종료 했을때 정상 종료 수행
			pygame.quit()




-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>

// 코딩이 완료 되었다면 실행해 보자.


user@user-test:~$ python py_piano.py



키보드의 키 1~8(도레미파솔라시도) 를 눌러 보고 눌렀다 때 보면서 음의 길이도 조절이 되는지를 테스트해 보자.



도움이 되셨다면 '♡' 버튼을 꼭눌러 주시면 감사 하겠습니다.


그리고 글에 부족한 점이 있거나 틀린 점, 더 궁금한 부분이 있는 것 같다면 꼭 댓글로 알려 주시 감사 하겠습니다.

         






중급 이상의 c언어 프로그래밍 개발자라면 파일 시스템의 활동 상태를 감시할수 있는 inotify 함수 응용에 대해서 알고 있을 것이다. 

본 포스팅은 리눅스에서 inotify를 응용한 C언어 코딩과 그 안의 시스템 함수를 응용 하여 쉘 컨트롤을 중첩 활용한 '디펜드 파일시스템 '를 설계하고 구현해 보고 '파일 시스템 방어 구축'에 관한 그 가능성을 짚어 보도록하는 데에 그 취지가 있다. 

우선 전체적인 원리는 단순하다.


글씨를 참 못쓴다. 누가 보면 초딩인줄 알겠다..... 참 나는 전자펜 으로 그리는 데에는 아직(?) 재주가 없다. 



중요한 것은 본 프로그래밍 가이드에 필요한 모듈에 필요한 함수가 의외로 많다는 것이고 특별한 헤더에는 "sys/inotify.h(파일 시스템 감독)" , "setjmp.h(지점 "sys/types.h (타입 파악)" 이 있다.

자 그렇다면 본격적인 프로그래밍을 해보도록 하자.

                 Source_File name : dfs.c             |             Type : C                  |                        |           


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define _Event_		( sizeof (struct inotify_event) )	/* Inotify 함수의 이벤트 처리를 위한 전처리 지정 */
#define Buffer_size	( 1024 * ( _Event_ + 64 ) )

jmp_buf point;	/* setjmp 모듈을 활용할 변수 지정 */

int main( int argc, char **argv ) {
	setjmp(point);	/* setjmp 함수 당 포인트를 셋팅 한다. */
	FILE *Write_file;	/* 로그 파일을 기록하기 위한 변수 선언 */

	char Fs_Path[4092]; /* 감시할 파일 경로를 입력받을 변수 */
	strcpy(Fs_Path, argv[1]);
	
	int ii;		/* 각 버퍼 사이즈 비교 대입 값을 위한 변수 */
	
	int Inotify_Buff; /* inotify 함수를 대입할 고정 버퍼값을 위한 변수 */
	
	char buffer[Buffer_size];	
	
	ii = inotify_init();	/* inotify 모듈을 초기화 로드 한다. */
	
int Back_Target() {
		char cpcon[2048] = "cp -rf ", bakpath[] = " /tmp/bak_path"; 	/* 파일 백업을 만들 변수 */
		system("rm -rf /tmp/bak_path");
		strcat(cpcon, Fs_Path);
		strcat(cpcon, bakpath);
		system(cpcon); /* 타겟 파일 백업을 만든다. */
	}
int syscon() {		/* 이벤트 발생시 해당 파일을 복원할 파일 시스템 제어 기초 함수 설계 */ 
		
		/* 시작 기존의 백업 파일을 삭제 */
		
		char Remove_Target[2048] = ("rm -rf ");		
		strcat(Remove_Target, Fs_Path);
		system(Remove_Target);
		
		/* 완료 기존의 백업 파일을 삭제 */
		
		/* 시작 변동시 복원을 위한 작업 */
		
		char Restore[2048] = "cp -rf /tmp/bak_path ";
		strcat(Restore, Fs_Path);
		system(Restore);
		
		/* 완료 변동시 복원을 위한 작업 */
		
		/* 시작 작업 내용 출력 및 시작 로그 기록 */ 
		
		Write_file = fopen("dfs.log", "a");
		fprintf(stderr,"\nTarget ' %s ' has restored.\n\n", Fs_Path);
		fprintf(Write_file, "Target ' %s ' has restored.\n\n", argv[1]);
		fclose(Write_file);
		
		/* 완료 작업 내용 출력 및 시작 로그 기록 */
	}


	if (ii < 0) {		/* 버퍼 비교에 의한 inotify 함수 초기화 */
		perror("inotify_init");
	}
	else
	
	system("date -R >> dfs.log; echo Defending_Start >> dfs.log");	/* 날짜 출력과 함께 로그 기록을 생성하고 시작 (존재 할시 이어서 기록한다. */
	
	if (argc < 2 ) { 	/* 외부 인자 값의 유.무를 파악 하여 작업 선언 */
		printf ("Do not start defend file system... Please running with insert Target path.\n\n BYE~!\n");
		exit (0);
	} else {
	
		if ( access(Fs_Path, F_OK) == -1 ) { /* 타겟 파일의 존재를 파악하여 없다면 종료 시킨다. */
			fprintf(stderr, "Target %s does not exist... to EXIT.", Fs_Path);
			exit (0);
		} 
	
		fprintf (stderr, "Defending start... \n File path = '%s' of systems\nIf you wnat exit to 'CTRL +C'.\n", argv[1]);

		Back_Target();	/* 타깃 파일을 백업 한다. */
	}
	
	Inotify_Buff = inotify_add_watch(ii, argv[1], IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO | IN_MOVE_SELF);	/* inotify 각 이벤트 발생에 따른 함수 실행을 위한 변수 지정 */
	
	while(1) {	/* 지정한  타겟 파일에 대한 반복 감시 시작 */ 
		int origin_size, i = 0;
		origin_size = read(ii, buffer, Buffer_size);
		if (origin_size < 0) {
			perror("read");
		}
		
		while ( i < origin_size ) {	/* 이벤트 발생을 위한 반복 수행 */
			struct inotify_event *event = (struct inotify_event *) &buffer[i];	

			fprintf(stderr, "\nVariance check = Wd : %d , Mask : %d , Cookie : %d , Length : %d , Type : %s\n\n", event->wd, event->mask, event->cookie, event->len, (event->mask & IN_ISDIR)?"Directory":"File");	/* 타깃 파일에 대한 변화를 감지 하여 변화된 실제 파일의 타입을 출력하고 로그를 기록한다. */
			
			system("date -R >> dfs.log");
			
			Write_file = fopen("dfs.log", "a");
			
			fprintf(Write_file, "\nVariance check = Wd : %d , Mask : %d , Cookie : %d , Length : %d , Type : %s\n\n", event->wd, event->mask, event->cookie, event->len, (event->mask & IN_ISDIR)?"Directory":"File");	/* 변화된 사항과 만일 타깃 디렉터레에 추가된 사항이면 그것이 어떤 타입인지 확인 */
			
			fclose(Write_file);

			if (event->mask & IN_CREATE) {	/* 타깃 디렉터리에서 파일이나 디렉토리가 생성 되었을 경우 이벤트 처리 */
			
				printf("\n %s was created. at Watching in Target Directory.\n\n", event->name);
				
				/* 시작 출력과 출력 로그를 기록한다. */
				
				Write_file = fopen("dfs.log", "a");
				fprintf(Write_file, "\n %s was created in Target Directory. \n\n", event->name);
				fclose(Write_file);
				syscon();
				}
				
				/* 완료 출력과 출력 로그를 기록한다. */
				
			else if (event->mask & IN_DELETE || IN_DELETE_SELF) {	/* 타깃에 삭제가 발생할 경우 이벤트 처리 */

				printf(" %s was deleted at Watching Target.\n", event->name);
						
				Write_file = fopen("dfs.log", "a");
				fprintf(Write_file, " %s was deleted at Watching Target. \n", event->name);
				fclose(Write_file);
				syscon(); 
				}
				
			else if (event->mask & IN_MODIFY ) {	/* 타깃에 변동이 발생 되었을 경우 이벤트 처리 */ 

				printf(" %s was modified at Watching Target.\n", event->name);
				Write_file = fopen("dfs.log", "a");
				fprintf(Write_file, "%s was created. at Watching Target of file system.\n", event->name);
				fclose(Write_file);
				syscon(); 
				}

			else if (event->mask & IN_MOVED_FROM || event->mask & IN_MOVED_TO || event->mask & IN_MOVE_SELF) {	/* 타깃에 대한 이동 발생시 이벤트 처리 */

				printf("%s was moved at Watching Target.\n", event->name);
				Write_file = fopen("dfs.log", "a");
				fprintf(Write_file, "%s was moved at Watching Target.\n", event->name);
				fclose(Write_file);
				syscon(); 
				}
			i = 0;
			longjmp(point, 1);	/* jmp 셋팅한 지점으로 다시 되돌아 간다. */
			}
		}
	return 0;
	}



코딩이 완료 되었으면 컴파일 하고 실행해 보자.

-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>

// 해당 파일을 컴파일 한다.


user@user-test:~$ gcc -f dfs dfs.c


// 컴파일된 프로그램을 실행해 본다.


user@user-test:~$ gcc -f dfs dfs.c


Do not start defend file system... Please running with insert Target path.


-> 하지만 코딩 했던것 처럼 인자값이 입력 되지 않으면 종료 된다.



이제 본격적으로 방어 능력을 테스트해 보자.




-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>

// 아무 파일을 만든다.


user@user-test:~$ echo 1 > /tmp/a

 

// 만든 파일을 실행과 함께 인자값으로 지정한다.


user@user-test:~$  ./dfs /tmp/a


Defending start... 
 File path = '/tmp/a' of systems
If you wnat exit to 'CTRL +C'.


-> 라는 문구와 함께 해당 파일에 대한 감시 및 방어를 시작한다.

// 다른 터미널을 열어 만든 파일을 변조해 공격해 보자.


user@user-test:~$ echo 2 > /tmp/a


Variance check = Wd : 1 , Mask : 2 , Cookie : 0 , Len : 0 , Type : File


Target ' /tmp/a ' has restored.

Defending start...
 File path = '/tmp/a' of systems
If you wnat exit to 'CTRL +C'.

->  변경된 속성과 타입 출력, 그리고 복원했다는 메시지가 나온다.


// 정말 복원 되었는지 확인해 보자.


user@user-test:~$ cat /tmp/a


1

-> 아까 입력한 대로 '1' 을 출력하였고 복원에 성공한 것을 확인했다.



그렇다면 이젠 디렉토리 복원을 테스트해 보자.

-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>

// 먼저 폴더를 만들고 파일 하나도 같이 만들자.


user@user-test:~$ mkdir /tmp/1 ; echo 1 > /tmp/1/2


// dfs로 디렉토리 방어를 시작해 보자


user@user-test:~$ ./dfs /tmp/1

Defending start...
 File path = '/tmp/1' of systems
If you wnat exit to 'CTRL +C'.


// 터미널을 새로 열고 변조를 통해 공격을 시도해 보자.


user@user-test:~$ rm /tmp/1/2


Variance check = Wd : 1 , Mask : 512 , Cookie : 0 , Len : 16 , Type : File


 2 was deleted at Watching Target.

Target ' /tmp/1 ' has restored.

Defending start... 
 File path = '/tmp/1' of systems
If you wnat exit to 'CTRL +C'.


-> 파일 '2'가 삭제 되었고 복원 하였다는 메시지가 출력한다.


// 마찬가지 복원을 확인하자.

user@user-test:~$ cat /tmp/1/2

1


-> 복원 성공을 확인할 수 있다. 



// 이번에는 타겟 폴더에 폴더를 생성해 보자.


user@user-test:~$ mkdir /tmp/1/3

Variance check = Wd : 1 , Mask : 1073742080 , Cookie : 0 , Len : 16 , Type : Directory



 3 was created. at Watching in Target Directory.


Target ' /tmp/1 ' has restored.

Defending start...
 File path = '/tmp/1' of systems
If you wnat exit to 'CTRL +C'.


-> '3' 폴더가 만들어 졌지만 복구 했다는 메세지가 출력 된다.



// 정말 복원 되었는지 확인하자.


user@user-test:~$ cd /tmp/1/3


-bash: cd: /tmp/1/3: 그런 파일이나 디렉터리가 없습니다


-> 정말 만든 폴더가 복원, 방어 되어 존재 하지 않는 것을 확인 할 수 있다. 


이뿐만이 아니라 해당 프로그램은 코드에서 봤다 시피 'dfs.log' 파일에 시간과 함께 작업 모든 기록을 보관 하고 있다.


-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>

// 지금까지 작업한 로그 기록을 확인해 보자.


user@user-test:~$ cat dfs.log



이로써 C언어로 설계한 디펜드 파일 시스템이 정상적으로 성능을 발휘 할 수 있는 것을 확인 할 수 있지만 코드를 보아서 알다시피 전지전능한 프로그램은 아니기에 폴더 안의 폴더 안에 발생하는 이벤트를 처리 하지는 못한다. 이를 해결하려면 더 추가적인 코딩이 필요하다.

또 마찬가지 실행시 마다 백업 경로를 단일로 갈아 치우는 단순한 방법을 사용 하기 때문에 이 프로그램을 활용하여 여러 프로세스로 실행해 실제 파일 시스템의 여러 중요 파일들을 한번에 방어 하지 못한다. 마찬가지 실전용으로 만들려면 bash를 적극 활용한 이중 교환적을 요구하는 높은 난이도의 복잡한 추가적 코딩이 요구된다.

하지만 이러한 방식으로 말미앎아 파일 시스템을 직접적으로 방어 할 수 있는 새로운 방식의 보안 시스템을 구축 할 수 있다는 것을 선 보인 좋은 계기가 될 것이며 파일을 변조 및 암호화 하여 비트코인을 달라 하는 랜섬웨어 악성코드 발동도 결과적으로 방어 할 수 있는 이상적 시스템을 구상할 수가 있다.

도움이 되셨다면 '♡' 버튼을 꼭눌러 주시면 감사 하겠습니다.


그리고 글에 부족한 점이 있거나 틀린점이 있는 것 같다면 꼭 댓글로 알려 주시면 감사 하겠습니다.



기본적으로 파일시스템은 프로그램 자체에 if문이나 case문으로 인자 ($1~10) 값을 처리하는 자동완성을 콘솔 밖에서 bash가 자동으로 잡아내지는 못한다.

그와 같은 응용 프로그램에 사용되는 자동완성 기능은 파일시스템의 '/etc/bash_completion'이 담당 하며 '/etc/bash_completion.d/~' 폴더를 들여다 보면 해당 프로그램에 대한 자동완성 기능이 있는 쉘 구축 파일들을 볼 수가 있다.

해당 파일들은 '/etc/bash_completion'가 처리 할 수 있는 함수들이 있으며 소크 코드의 형태를 이해하면 여러분도 직접 만든 응용 프로그램에 대한 자동완성 인자 값 추가 기능을 파일 시스템에 도입 할 수가 있다.

자 그렇다면 쇠뿔도 단 김에 빼라고 곧바로 소스코딩에 들어가 보자.

먼저 실행 가능한 $PATH에 실행 가능한 프로그램이 있어야 한다. 

그래서 간단한 shell 프로그램을 설계해 보자.

Source_File name : friend.sh

[Download]  

Type : bash

클립보드로 복사 → (본문 클릭)

무제



위는 인자 쉘에서 인자값을 인지하여 출력하는 간단한 대화형 출력 프로그램 이다.

완성 되었으면 간단하게 테스트를 해보자.

-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>

// 파일명을 'friend'로 바꾼다음 실행을 가능케 속성을 추가한다.


user@user-test:~$ mv friend.sh frined && chmod +x friend


user@user-test:~$  ./friend hi

hello


user@user-test:~$  ./friend bye

see you tomorrow~!


// 되었으면 $PATH로 복사 한다.


user@user-test:~$  sudo cp friend /usr/bin/


// 테스트 해본다.


user@user-test:~$ friend

what?


자 이제 간단한 인자값 인지 프로그램을 만들었으니 이제는 이 프로그램을 자동 완성 시켜주는 소스를 설계해 보자.


Source_File name :friend.bash_completion

[Download]

Type : bash

클립보드로 복사 → (본문 클릭)

무제


설계가 끝났으면 만든 파일을 '/etc/bash_completion.d' 로 복사하자.

-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>


user@user-test:~$ sudo cp friend.bash_completion /etc/bash_completion.d



// 그리고 테스트 해보자.


// '/etc/bash_completion' 를 호출해주는 '~/.bashrc'를 로딩 한다.



user@user-test:~$ source ~/.bashrc



user@user-test:~$ friend '⇔'(탭키 연타)


hi    bye



> 자동 완성이 성공했다.



그리고 중요한 friend.bash_completion 파일의 소스코드 구조는 다음 그림과 같다. 



  

도움이 되셨다면 '♡' 버튼을 꼭눌러 주시면 감사 하겠습니다.


그리고 글에 부족한 점이 있거나 틀린점, 혹은 틀린 부분이 있는 것 같다면 꼭 댓글로 알려 주시면 감사 하겠습니다.




awk 프로그래밍 가이드1 [링크] 에서는 awk를 활용해 텍스트 파일의 원하는 열만 출력하는 것을 배웠다


이번 가이드2 에서는 awk를 활용해 원하는 텍스트 파일의 첫번째 행에 원하는 열을 추가 하여 출력 하는 것을 배워 볼 것이다.

먼저 예제 파일의 구조는 다음과 같다.

file

1 jaen 24 male
2 lesser 32 female
3 kerten 15 male




본격적으로 위 파일에 수식어가 담긴 행을 입혀 출력해 보자.

-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>

// 주석


root@test:~$ awk 'BEGIN{printf "No\tName\tOld\tGender\n"} {print}' file


No Name Old Gender
1    jaen     24 male
2    lesser   32 female
3    kerten  15 male


->위와 같이 출력 된다.





간단한 원리는 다음 그림과 같다.



다른 파일(file2)로의 저장 응용은 다음과 같다.

-- 터미널 텍스트 박스 (Terminal text box) --

<Drag와 복사가 가능합니다.>


root@test:~$ awk 'BEGIN{printf "No\tName\tOld\tGender\n"} {print}' file > file2





다음 가이드3에서는 awk 프로그래밍에 대한 기본적인 언어 습득과 awk 스크립트를 내장하고 있는 파일을 호출하여 다루는 방법에 대하여 포스팅할 예정이다.


도움이 되셨다면 '♡' 버튼을 꼭눌러 주시면 감사 하겠습니다.






+ Recent posts