반응형

누나가 사용하던 손풍기가 충전은 잘 되지만 동작하지 않는 문제로 고쳐달라하여 고치게 되었다.

 

먼저 손풍기의 밑 고무패드를 뜯으면 나사가 나오는데 이 나사를 풀면 첫번째 단계는 완료이다.

 

그 다음이 어려운데.. 

다음과 같은 툴킷이 있다면 틈을 따라서 쭉 밀면서 열어주면된다.
(툴킷은 알리익스프레스에서 구매한다면 얼마하지 않으므로 하나쯤 있으면 분해 등 여러 일에 도움이 된다. 참고로 알리익스프레스에 카카오페이가 지원된다고 하니

구매하기 간편할 것이다.)


밑 손잡이 부분은 열기 쉬우나 윗부분은 열기 어려울 것이다. 따라서 밑의 그림과 같이 결착된 부분의 중간쯤을 벌려서 분해한다면 그나마 쉽게 열릴 것이다. 

 

 

분해를 해보니 배터리와 보드를 연결해주던 부분이 떨어져 있었다. 아마 충격으로 인하여 서서히 끊어진것이 아닐까 추정한다....

따라서 저 부분을 접촉 시켰을 때 당연히 잘 동작하였다.

(납땜만하면 수리가 완료이지만 집에 놔둔 인두기를 못찾아서 다음에 남땜을 하고 다시 자세히 올려야겠다..)

728x90
반응형
블로그 이미지

아상관없어

,

Github SourceTree

공부/기타 2020. 9. 3. 15:27
반응형

Commit = 스테이지에 올린 파일들을 묶고 스냅샷

Pull = 원격 저장소에 있는 모든 커밋 다운로드

Push = 로컬에서 원격으로 업로드 ( Commit시 로컬에 저장되므로 Push함)

Patch = 새로고침

Branch = 새로운 기능 추가할 때 사용, Branch 생성

Merge = 두 Branch를 합침

Stash = 작업 도중 브랜치 바꿈, 임시 저장공간 ( 신규 파일은 되지 않는다 = 변경사항이 없기 때문), 이전 commit 덮어씀

Git Flow

- master : 기준 브랜치

- develop : 개발 브랜치, 이 브랜치 기분으로 작업한 기능 merge함

- feature : 단위기능 개발 브랜치, 완료후 develop과 merge

- release : QA 품질검사

- hotfix : 배포후 버그가 생겼을때 긴급수정

 

 

ex)

1. master 브랜치에서 시작

2. 동일 브랜치 develop에 생성

3. develop에서 개발

4. 기능 구현 필요시 feature 브랜치로 각자 기능 구현후 develop과 merge

5. 모든 기능 완료시 develop 브랜치를 release 브랜치로 만들어버림

6. 모든 것이 완료되면 release 브랜치를 master와 develop브랜츠로 보냄

7. 버그 발생시 hotfix 브랜치를 만들어 수정

 

fork 하여 프로젝트 복사후, 각자 개발하여 fork한 원격 저장소에 push하고 메인 원격 저장소에 pull request함

 

1. github을 clone

2. add하여 스테이지에 올림

3. 커밋하여 변경사항 저장

4. 원격저장소에 push

 

728x90
반응형
블로그 이미지

아상관없어

,
반응형

글머리1(# _)

글머리2(## _)

글머리3(### _)

글머리4(#### _)

글머리5(##### _)

글머리6(###### _)

강조

italic = * a *, _ a _

*italic*

_italic_

굵은 글씨 = ** a **, __ a __

**굵은 글씨**

__굵은 글씨__

줄 긋기 = ~~ _ ~~

~~줄긋기~~

굵은글씨 italic = **_

**_굵은글씨 italic_**

인용구

앞에 > 붙임

인용구 테스트

숫자

숫자와 점을 이용

  1. 첫번째
    1. 세부1
    2. 세부2
  2. 두번째
  3. 세번째

목록

*, +, -

각각 순서대로

  • star
    • plus
      • minus

외부 링크

[] = 타이틀 () = 링크

[naver](https://naver.com)

수평선 줄



<hr/>

-연속

*연속

< hr/ >

이미지

[![Picture]()

]

코드 강조

`` 코드 묶기(역따옴표 씀)

글을 쓰다가 코드 강조시 `printf("hello world")`로 하면 된다.

코드 전체 삽입

` 3번 입력 후 사용언어 입력

b = 1; c = 1;

문법 연습.md
0.00MB

728x90
반응형
블로그 이미지

아상관없어

,
반응형

현재 아이폰8을 사용중인데 배터리 성능 최대치가 처참하여 교체를 고려하였다. 

 

 

출시된지 꽤 되었고 쓰다가 바꿀 계획이었고, 애플의 사악한 가격을 구경하고 자가교체를 하게 되었다.

 

자가교체시 노혼 배터리가 가장 유명하지만, 다음의 사이트에서 https://gigglehd.com/gg/mobile/7112312 아이폰 배터리관련 글을 보게되었다. 간략하게 요약하자면, 러시아의 BatteryLab이라는 업체에서 사제 배터리들을 테스트한 결과 노혼 배터리의 수명이 생각보다 좋지 않은 결과를 보여주었고 AYJ사의 배터리가 가장 좋은 효율을 보여주었다는 것이다. 하지만 몇 개의 배터리로 테스트를 한 결과인지 알 수 없어 참고 정도로만 하였다. 그러던 중 DEJI사의 배터리를 알게 되었다. 

 

 

한국 총판도 있고, 여러 인증들을 받아서 이 업체에서 사기로 했다.(노혼은 이미 유명하여 짭이 많아서 이 브랜드를 선택했다.) 

알리에서 사려고 하였으나 마침 옥션 쿠폰이 있어 국내에서 19000원 가량에 구입하였다.

 

 

사은품으로 배터리 테이프와 드라이버 핀셋 등을 함께 받았다. 

액정을 열때는 헤어드라이기 보단 집에 남아도는 찜질팩이 최고인 것 같다. (전에 핫팩으로도 하였는데 나쁘지 않았다.)

 

 

 

 

여는 것만 잘하면 나머지는 ifixit이나 다른 유튜브 동영상을 적절히 검색하여 따라서 하면 된다. 하지만 우선 가장먼저 배터리를 연결해제 하는 것을 추천한다. 건조한 환경에서는 가끔 쇼트가나서 아이폰의 부품 몇개가 죽을 수 도 있다. (실제로 아이폰 7 지문인식을 날려먹기도 하였다.)

 

 

 

 

분해시 꼭 나사 위치를 정확히 해놓는 것이 좋다. 아니면 나사가 맞지 않거나 나사가 몇개 남는데 휴대폰이 동작하는 경우를 볼 수 있다.(실제로 아이폰3GS, 아이폰 4 사용시 경험하였다.)

 

 

 

 

유튜브 동영상으로 배터리 테이프를 제거하는 영상을 잘 보고 따라하길 바란다. (ifixtit 사진만 보고 참고할 시 저런 사태가 벌어질 수도 있다.)

 

참고로 ifixit에서는 디스플레이와 안테나, 탭틱 엔진을 분리하고 배터리를 분해하여라 하는데 그냥 배터리 케이블만 분리하고 바로 테이프를 제거하는 것이 훨씬 편했다. 괜히 동영상을 보지 않고 ifixtit만을 보았다가 탭틱엔진 분해시 케이블을 조금 찢어먹었다....


여튼 조립은 분해의 역순이라는 진리의 말대로 하면 (조립시 새 방수테이프와 배터리 테이프를 잘 붙여야한다.)

 

 

배터리 교체 완료이다. 

교체 후 7일 정도가 되었는데 

 

 

25사이클 정도 사용하였고, 아직 성능최대치는 100%이다. (저 기능을 사용하고 싶으면 개인정보보호 - 분석 및 향상에서 분석 공유를 활성화하고 분석데이터에서 log-aggregated 항목을 살펴보면 된다. 귀찮을시 iBackup과 같은 툴을 사용하길 바란다.)

 

 

 

 

참고로 대용량 배터리들도 있으나, 혹시 모를 스웰링 발생가능성을 배제할 순 없기 때문에 정품과 동일한 용량을 선택하였다. (내부 디자인도 신경을 쓰는 애플이 배터리 공간에 여유를 둔건 이유가 있을 것이다.. 괜히 배터리타임 조금 늘리려다 화면을 깨먹는 불상사를 발생시킬순 없기에..)

그리고 탭틱엔진을 날려먹어서 진동이 없지만 애플워치가 있는 덕분에 전화나 카카오톡을 확인하는데는 별 지장이없어 천천히 수리하기로 하였다... ㅠ

 

 

 

음... 사설을 가야겠다 ㅎㅎ...

(참고로 저 부품은 시리얼 넘버가 일치하지 않으면 작동을 하지 않으므로 icopy plus와 같은 기계로 원래 부품의 시리얼 넘버를 복사하여 알리발 부품에 붙여넣기를 해주어야 작동을 한다. 그렇지 않을 경우 홈버튼 진동만 오고 다른 진동은 작동하지 않는다고 한다.)

728x90
반응형
블로그 이미지

아상관없어

,
반응형

The.Mick.S02E05.720p.HDTV.x264-AVS.srt
0.04MB

비록 캔슬되었지만... 시즌2가 보고 싶어 작년에 만든 자막입니다. 개강으로 인해 5화까지만 하였습니다...ㅠㅠ

728x90
반응형

'기타 > 자막' 카테고리의 다른 글

The mick 시즌2 4화 자막  (0) 2020.07.31
The mick 시즌2 3화 자막  (0) 2020.07.31
The mick 시즌2 2화 자막  (0) 2020.07.31
The mick 시즌2 1화 자막  (0) 2020.07.31
블로그 이미지

아상관없어

,
반응형

The.Mick.S02E04.720p.HDTV.x264-AVS.srt
0.04MB

비록 캔슬되었지만... 시즌2가 보고 싶어 작년에 만든 자막입니다. 개강으로 인해 5화까지만 하였습니다...ㅠㅠ

728x90
반응형

'기타 > 자막' 카테고리의 다른 글

The mick 시즌2 5화 자막  (0) 2020.07.31
The mick 시즌2 3화 자막  (0) 2020.07.31
The mick 시즌2 2화 자막  (0) 2020.07.31
The mick 시즌2 1화 자막  (0) 2020.07.31
블로그 이미지

아상관없어

,
반응형

The.Mick.S02E03.720p.HDTV.x264-AVS.srt
0.04MB

비록 캔슬되었지만... 시즌2가 보고 싶어 작년에 만든 자막입니다. 개강으로 인해 5화까지만 하였습니다...ㅠㅠ

728x90
반응형

'기타 > 자막' 카테고리의 다른 글

The mick 시즌2 5화 자막  (0) 2020.07.31
The mick 시즌2 4화 자막  (0) 2020.07.31
The mick 시즌2 2화 자막  (0) 2020.07.31
The mick 시즌2 1화 자막  (0) 2020.07.31
블로그 이미지

아상관없어

,
반응형

The.Mick.S02E02.720p.HDTV.x264-AVS.srt
0.05MB

비록 캔슬되었지만... 시즌2가 보고 싶어 작년에 만든 자막입니다. 개강으로 인해 5화까지만 하였습니다...ㅠㅠ

728x90
반응형

'기타 > 자막' 카테고리의 다른 글

The mick 시즌2 5화 자막  (0) 2020.07.31
The mick 시즌2 4화 자막  (0) 2020.07.31
The mick 시즌2 3화 자막  (0) 2020.07.31
The mick 시즌2 1화 자막  (0) 2020.07.31
블로그 이미지

아상관없어

,
반응형

The.Mick.S02E01.720p.HDTV.x264-AVS.srt
0.04MB

비록 캔슬되었지만... 시즌2가 보고 싶어 작년에 만든 자막입니다. 개강으로 인해 5화까지만 하였습니다...ㅠㅠ

728x90
반응형

'기타 > 자막' 카테고리의 다른 글

The mick 시즌2 5화 자막  (0) 2020.07.31
The mick 시즌2 4화 자막  (0) 2020.07.31
The mick 시즌2 3화 자막  (0) 2020.07.31
The mick 시즌2 2화 자막  (0) 2020.07.31
블로그 이미지

아상관없어

,
반응형
void setup() {
  // 센서값을 측정하기위해 시리얼통신을 준비합니다.
  Serial.begin(9600); 
}

void loop() {
  //아날로그 0번 핀에 압력센서를 연결합니다.
  int sensorval = analogRead(A0);

  

  
   
  Serial .println("Sensorvalue : " +String(sensorval));
  
  //100ms동안 대기합니다. 
  delay(100);
}

 아날로그 핀을 사용하였다.

728x90
반응형

'공부 > 아두이노' 카테고리의 다른 글

아두이노 온습도 센서  (0) 2020.07.18
아두이노 미니 스마트홈  (0) 2020.07.17
아두이노 센서 여러개 사용시 에러  (0) 2020.07.17
블로그 이미지

아상관없어

,
반응형
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
}
void loop() {
  delay(2000);
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.println(" C");
}

datapin은 2번핀이다.

728x90
반응형

'공부 > 아두이노' 카테고리의 다른 글

아두이노 압력센서  (0) 2020.07.18
아두이노 미니 스마트홈  (0) 2020.07.17
아두이노 센서 여러개 사용시 에러  (0) 2020.07.17
블로그 이미지

아상관없어

,

괌 - 해적버거

기타/여행 2020. 7. 17. 15:59
반응형

해적버거 야외 테라스 자리의 뷰이다.

 

괌에서 좋았던 점은 닥터 페퍼가 거의 모든 식당에서 판다는 것이다.

버거를 시키면 반으로 쪼개져서 나온다. 아마 채소들이 눅눅해지지 않게하기 위해서인 것 같다. 

양이 겁나 많다. 다른 식당도 많았지만 여긴 더 배불렀던것 같다. 감자튀김은 그냥 아는 맛이니 먹는 양이 작으면 버거 단품을 추천한다. 버거는 쉐이크 쉑과 다르게 기름지다기 보단 담백한 고기였다. 빵은 어느정도 촉촉하나 목이 막히는건 똑같다. 맛은 있었지만 지나가는 길이 아니라면 도스버거를 가는게 나을 것 같다.

728x90
반응형
블로그 이미지

아상관없어

,

정렬하기

공부/자료구조 2020. 7. 17. 15:24
반응형

InsertRand.c
Sort.h
Sort.c
Makefile

728x90
반응형
블로그 이미지

아상관없어

,
반응형

정찰

최신의 자동차들은 ECU라고 불리는 전자 제어장치를 장착한다. 차량에는 편의 기능을 위하여 장착된 ECU수가 많다.  이들간 통신을 위해 CAN이라는 단일버스 네트워크를 사용한다. CAN은 외부 네트워크에서 적용되는 보안기법에 취약하다. ICT와 융합된 커넥티드 카는 운행 중에도 외부네트워크와 항상 연결이 되어있고, 통신장치를 자동차에 장착할 수 있다. 커넥티드 카는 ECU들로 내부 네트워크를 구성한 자동차, 네트워크 서비스를 제공하는 Portal 그리고 자동차와 Portal을 연결해주는 통신 Link로 이루어져있다. 출고 시 기본 장착되는 통신장치 외에 third-party 통신장치가 추가 장착이 가능하다. 이 통신장치로 정보를 수집하거나 외부에서 원격으로 차를 조종할 수 있다. 운전자들은 스마트폰과 자동차간의 통신을 이용해 다양한 편의기능을 사용한다. 웹기반과 스마트폰 앱 기반 서비스로 자동차와 통신을 할 수 있다. 안드로이드 앱을 사용하는 경우, 역공학과 리패키징의 취약한 문제점이 있다.

이러한 After Market에서 판매되는 H/WS/W의 사용이 가능하다. 자동차 내부 네트워크와 자동차용 정비기기 사이의 통신을 지원하는 마이크로 컨트롤러인, ELM327기반의 무선통신 모듈을 사용하여 스마트폰과 자동차 내부 네트워크를 무선을 연결 할 수 있다. ELM327 제조사는 관련 H/WS/W를 제작할 수 있는 Data Sheet를 제공한다.

 

무기화

CAN의 보안 취약점과 안드로이드 앱의 역공학, 리패키징 취약점, 차량과 스마트폰과의 통신을 이용하여 무기화를 한다.

스마트폰 앱과 자동차간 통신이 가능한 점을 이용하여, 안드로이드 앱을 리패키징하여 악성앱을 제작한다. ADB Shell을 사용하여 정상적인 앱의 APK파일을 획득하고, 획득한 APKDEX(소스 코드를 컴파일한 결과물)파일을 획득한다. DEX파일이 가상머신에서 동작하는 바이트코드의 구조적 특징을 가진다는 점을 이용하여, 원본과 유사한 Java코드와 Smali코드를 얻는다. 분석을 하여 Smali코드에서 악성코드를 추가한다. 그리고 안드로이드 정책상 개발자 스스로 앱에 서명을 하여 배포하므로 임의로 서명을 하여 악성 앱을 배포할 수 있다.

자동차 진단 앱과 통신 모듈 ELM327의 통신을 이용하여, 앱에서 발생하는 통신데이터를 변경한다. 변조된 앱을 사용하여 ECU 강제 제어 데이터프레임을 CAN에 삽입하여, 정비용 CAN ID를 원하는 CAN ID로 변환한다. 모듈 Data Sheet를 참조하여 모듈을 제어할 수 있는 AT Command들을 획득한다. AT Command들을 이용하여 실제 CAN으로 원하는 CAN ID로 변환하여 원하는 데이터를 전송한다. 

CAN은 각 노드 간 통신시 암호화와 인증이 되어있지 않는 취약점이 있다. 앱으로 통신 모듈 ELM327과 블루투스로 통신될 때, Request-Response 메시지를 획득하여 자동차의 상태 정보를 획득한다. Java 기본함수 탐색을 통해 Smali 코드에 자동차 강제제어 코드를 삽입할 곳을 찾는다. 악성 앱에서 필요한 공격 Smali코드를 추출하고 공격 대상 앱에 적용하여 변조한다. 자동차의 상태 정보를 획득한 뒤, 특정 조건일 때, 변조된 앱으로 원래의 Request 메시지 대신 원하는 메시지로 변경하고 차량을 제어한다.

 

유포

자동차 정비 앱의 디자인을 바꿔 새로운 앱이 출시된 것처럼 가장한다. 그리고 가짜 광고를 통해서 자동차 정비 앱이 필요한 사용자들에게 홍보를 한다. 무료로 다운받을 수 있는 링크를 제공하여 사용자의 다운을 유도한다. 초기에는 정상적인 앱처럼 정상 작동을 하다 어느 시점이 지나면 코드가 동작이 되게 하여, 초기 사용자들이 좋은 평점을 남기게 한다. 그 평점을 이용하여 더 많은 사용자들의 다운을 유도한다. 또는 유료앱이 필요한 사용자들을 노린다. 악성 앱을 유명한 유료앱의 디자인으로 바꾸는 등 속이기 위한 위장을 하고, 블랙마켓, 앱에 대한 사전심사, 검사를 하지 않는 앱마켓 등에 뿌리고 사용자들의 다운로드, 설치를 유도한다.

 

악용 및 설치

사용자가 변조된 자동차 정비 앱을 다운로드, 설치 후 변조된 앱으로 자동차와 통신을 한다.

 

명령 및 제어

사용자가 변조된 앱을 다운로드, 설치 후 자동차와 통신을 함으로써, 악성코드가 심어진다. 그 후, 자동차는 사용자의 제어와 상관없이 심겨진 악성코드의 제어대로 움직이게 된다.

 

목적달성

공격자의 코드대로 차를 제어하여, 특정한 시점 또는 즉시, 운전자의 운전 제어를 방해한다.

.

 

 

 

공격 프로세스

사이버킬체인 사이버공격 설명
정찰 정보수집 자동차의 전자 제어장치와 내부 네트워크를 조사하고, 외부에서 접근할 수 있는 수단 등을 조사한다. 취약점이 나올만한 관련 정보도 모두 수집한다.
무기화 공격준비 정보수집 단계에서 수집한 정보들을 활용한다.
통신 모듈 ELM327로 앱, 자동차가 보안이 되지 않은 통신을 한다. CAN의 보안 취약점을 활용하여 자동차 내부 네트워크를 제어한다. 안드로이드 앱의 역공학, 리패키징을 이용하여 악성앱을 만든다. 위 두 취약점을 이용하여 앱으로 자동차 내부 네트워크를 제어하게 설계한다.
유포 유포 악성 앱을 새로운 앱처럼 홍보, 무료 다운로드 링크를 제공한다. 블랙마켓, 앱에 대한 사전 심사, 검사를 하지 않는 앱마켓에 악성앱을 유포한다.
악용 악용 사용자가 악성 앱을 다운로드하고 설치한다.
설치 설치 사용자가 악성 앱으로 자동차와 통신을 하면 ECU 강제 제어 데이터프레임이 CAN에 삽입된다.
명령 및 제어 명령 및 제어 악성 앱에 심어진 코드대로 자동차가 제어된다.
목적 달성 목적달성 특정 시점 혹은 항상, 운전자가 자동차를 제어하지 못하게 하거나 운전을 방해한다.

 

공격방법

정찰 단계에서 자동차의 공격점들을 찾아 무기화 단계에서 다음과 같은 취약점들을 이용하였다. 자동차 OBD-II 단자에는 여러 모듈을 장착할 수 있고 CAN은 추가된 ECU를 식별하지 못하며, 통신 참여를 제어하지 못한다. 정비 모듈을 사용하여 자동차 진단 앱과 통신을 할 수 있다. 안드로이드 역공학, 리패키징을 이용하여 악성 앱을 제작할 수 있다. CAN의 보안은 암호화/인증이 되지 않는다. 이러한 Attack Surface들을 찾아내어, 정상적인 앱을 역공학, 리패키징하여 악성코드를 추가한다. 이렇게 변조를 하여 악성 앱을 제작한다. 그리고 이 악성 앱을 유포, 설치한다.  OBD-II 단자를 통해 통신 모듈을 추가한 뒤, 변조된 악성 앱으로 통신을 한다. AT Command로 원하는 데이터를 전송하여 자동차를 제어한다.

 

방어기법

정상적인 앱을 악성 앱으로 역공학하기 어렵게 한다. 정상적인 자동차 정비 앱을 만들 때, 식별자 변환, 제어 흐름, 암호화 기법, API 은닉 기법을 사용한다. 자동차 정비 앱에서 분석의 대상은 주로 개발상 사용되는 일부 문자열과 함수이기 때문에 위 기법들로 난독화 과정을 한다. 이러한 과정들로 APK의 중요 로직이나 코드, 리소스 등을 보호한다. 무기화 단계의 안드로이드 앱의 취약점을 방어하고, 유포, 악용, 설치 단계를 하지 못하게 하여 결국 명령 및 제어를 막는다. 따라서 목적달성을 실패하게 한다.

ELM327 통신 모듈이 제어 명령으로 정상적인 정비 ID 이외에 원하는 CAN ID의 데이터를 생성할 수 있어 자동차를 강제 제어 할 수 있다. 따라서 ELM327 모듈이 정비용 ID만 사용하도록 설계를 한다. 무기화 단계의 CAN의 보안 취약점을 방어한다. 따라서 설치 단계의 ECU 강제 제어 데이터프레임을 CAN에 삽입하지 못하게 한다.

OBD-II 단자는 여러 통신 모듈을 장착 할 수 있으므로 ELM327외에 다른 모듈이 취약점이 될 가능성이 있다. 따라서 CAN 데이터에 대한 접근제어를 해야한다. 자동차를 정비 중과 주행 중으로 구분을 한다. 정비 중일 경우 모든 CAN ID의 접근제어를 해제하고, 주행 중일 경우 특정 CAN ID데이터만 접근 가능하도록 필터링한다. 무기화 단계의 CAN의 보안 취약점을 방어하여 내부 네트워크에 접근, 제어를 하기 어렵게한다.

 

단계별 방어기법

공격 전 단계 공격시도 단계 공격 후 단계
정찰 무기화 전달 익스플로잇 설치 C&C 행동개시
OBD-II 단자 접근 제어 안드로이드 앱 난독화 정상적인 앱마켓 사용 Threat Emulation Anti-Bot Anti-Bot Anti-Bot
ELM327 Data Sheet 허가된 사용자만 사용 CAN 통신 암호화 Anti-Spam Anti-Virus CAN ID 접근 제어 Endpoint Security Endpoint Security
CAN 통신 암호화 CAN 데이터 접근제어 URL Filtering 인증된 앱만 설치 Intrusion Prevention System
Data Leak Prevention   Mobile Threat Prevention Mobile Threat Prevention
  Threat Emulation Threat Emulation
Threat Extraction Intrusion Prevention System
728x90
반응형

'공부 > 보안' 카테고리의 다른 글

set-UID Privileged programs  (0) 2020.10.15
운영체제보안 4  (0) 2020.09.22
운영체제보안 3  (0) 2020.09.16
운영체제 보안 2  (0) 2020.09.10
운영체제 보안 1  (0) 2020.09.10
블로그 이미지

아상관없어

,
반응형

ECB_BMPFileEncryption.java ▼

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.*;

public class EcbMode {

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

    KeyGenerator kg = KeyGenerator.getInstance("DES");
    kg.init(new SecureRandom());
    SecretKey secretKey = kg.generateKey();

    FileInputStream inFile = new FileInputStream("c:/simpsons.bmp");

	
    Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);

    FileOutputStream outFile = new FileOutputStream("ECB_simpsons.bmp");

    byte[] input = new byte[64];
    int bytesRead;
    while((bytesRead = inFile.read(input)) != -1){
        byte[] output = cipher.update(input,0,bytesRead);
        if(output != null)
            outFile.write(output);
    }

    byte[] output = cipher.doFinal();
    if(output != null)
        outFile.write(output);

    inFile.close();
    outFile.flush();
    outFile.close();
    }
}

KeyGenerator keyGenerator = KeyGenerator.getInstance("DES"); //DES알고리즘으로 키 생성 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //DES알고리즘, ECB(Electronic Code Block) Mode 암호화 방식, Padding

 

CBC_BMPFileEncryption.java▼

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.*;

public class CbcMode {

    
     // @param args the command line arguments
     
    public static void main(String[] args) throws Exception{
         //TODO code application logic here

	//키 발생기 kg 선언 DES형태
    KeyGenerator kg = KeyGenerator.getInstance("DES");
    kg.init(new SecureRandom());//랜덤값으로 키 초기화
    SecretKey secretKey = kg.generateKey();//비밀키 생성

    FileInputStream inFile = new FileInputStream("simpsons.bmp");
	//현재폴더에서 simpsons.bmp 불러옴
	
    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");//DES알고리즘/ECB모드/패딩함
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);

    FileOutputStream outFile = new FileOutputStream("CBC_simpsons.bmp");

    byte[] input = new byte[64];
    int bytesRead;
    while((bytesRead = inFile.read(input)) != -1){
        byte[] output = cipher.update(input,0,bytesRead);
        if(output != null)
            outFile.write(output);
    }

    byte[] output = cipher.doFinal();
    if(output != null)
        outFile.write(output);

    inFile.close();
    outFile.flush();
    outFile.close();
    }
}

KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");

//DES알고리즘으로 키 생성

Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

//DES알고리즘, CBC(Cipher Block Chaining) Mode 암호화 방식, Padding

 

CTR_BMPFileEncryption.java▼

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.*;

public class CtrMode {

    
     // @param args the command line arguments
     
    public static void main(String[] args) throws Exception{
         //TODO code application logic here

	//키 발생기 kg 선언 DES형태
    KeyGenerator kg = KeyGenerator.getInstance("DES");
    kg.init(new SecureRandom());//랜덤값으로 키 초기화
    SecretKey secretKey = kg.generateKey();//비밀키 생성

    FileInputStream inFile = new FileInputStream("simpsons.bmp");
	//현재폴더에서 simpsons.bmp 불러옴
	
    Cipher cipher = Cipher.getInstance("DES/CTR/PKCS5Padding");//DES알고리즘/ECB모드/패딩함
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);

    FileOutputStream outFile = new FileOutputStream("CTR_simpsons.bmp");

    byte[] input = new byte[64];
    int bytesRead;
    while((bytesRead = inFile.read(input)) != -1){
        byte[] output = cipher.update(input,0,bytesRead);
        if(output != null)
            outFile.write(output);
    }

    byte[] output = cipher.doFinal();
    if(output != null)
        outFile.write(output);

    inFile.close();
    outFile.flush();
    outFile.close();
    }
}

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

//AES알고리즘으로 키 생성

Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5Padding");

//AES알고리즘, CTR(Counter) mode 암호화 방식, Padding

여기서 같이 암호화된 헤더파일 부분을 수정해주면 볼 수 있게 된다

 

728x90
반응형
블로그 이미지

아상관없어

,
반응형

 

#include <Servo.h>
#include "DHT.h" 
#include <SoftwareSerial.h>

Servo myservo;
Servo Tapservo;
int force_sensor1 = A0;
int force_sensor2 = A1;
int water = A3;

//블루투스 모듈
#define blueTX 5  // BT_TXD를 5로 설정합니다.
#define blueRX 13  // BT_RXD를 13으로 설정합니다.

SoftwareSerial mySerial(blueRX, blueTX);
//5, 13번 data pin사용

int ledPin_bath= 2;

int dhtPin = 3;

int servoPin = 4;

int servoTap = 6;

int ledPin_room = 7;

int Relaypin = 9;

int count = 0;
int alarm = -1;
int ButtonSwitch =0;

//초음파 센서
#define echoPin 12                    // echoPin을 12로 설정합니다.
#define trigPin 11                   // trigPin을 13으로 설정합니다.
//12~13 data pin사용

long duration, distance;

DHT dht(dhtPin,DHT11);

int old_force1=0;
int val = 0;

int angle = 0;

void setup() {
  // put your setup code here, to run once:
   
  Serial.begin(9600);

  mySerial.begin(9600);

  myservo.attach(servoPin);
  Tapservo.attach(servoTap);

  pinMode(Relaypin, OUTPUT);
  
  pinMode(ledPin_bath, OUTPUT);
  pinMode(ledPin_room, OUTPUT);
  
  pinMode(force_sensor1, INPUT);
  pinMode(force_sensor2, INPUT);
  
  pinMode(trigPin, OUTPUT);   // trigPin 핀을 출력핀으로 설정합니다.
  pinMode(echoPin, INPUT);    // echoPin 핀을 입력핀으로 설정합니다.
}

void loop() {

  // put your main code here, to run repeatedly:
  int level = analogRead(water);  // 수분센서의 신호를 측정합니다.


  int force_val1 = analogRead(force_sensor1); 
  int force_val2 = analogRead(force_sensor2);

  
 int angle1 = 0;

//블루투스 모듈 (begin)
  if (mySerial.available()) {
    Serial.write(mySerial.read());  //블루투스측 내용을 시리얼모니터에 출력
    alarm = 1;
    ButtonSwitch++;
    if(ButtonSwitch>1){
      ButtonSwitch=0;
    }
    else if(ButtonSwitch==0){
      alarm=-1;
    }
    if(alarm==1){
      Serial.println("All Sensors ON");
      digitalWrite(ledPin_room, HIGH);
      digitalWrite(ledPin_bath, HIGH);
      digitalWrite(Relaypin, HIGH);
      for(angle1 = 180; angle1 > 0; angle1--) 
      { 
        Tapservo.write(angle1); 
        delay(5); 
      }
    }
    else{
    Serial.println("All Sensors OFF");
    }
  }
  if(Serial.available()){
    mySerial.write(Serial.read());
  }
//블루투스 모듈 (end)




//릴레이1채널 + 진동
/*
  if(val == 1){
    digitalWrite(Relaypin, HIGH);
  }
  else{
    digitalWrite(Relaypin, LOW)
  };*/
//
 
//물 센서
  Serial.println(String("water level :")+level);
//  delay(100);
  if(level >500 && count == 0){
    for(angle1 = 0; angle1 < 180; angle1++) 
    { 
      Tapservo.write(angle1); 
      delay(5); 
      count++;
    }
    angle1 = 0; 
  }

  if(level < 500){
    count = 0;
  }

//압력
  Serial.println("first : "+String(force_val1));
//  delay(100);
  Serial.println("second : "+String(force_val2));
//  delay(100);


//초음파 센서 (begin)
  digitalWrite(trigPin, LOW);                 // trigPin에 LOW를 출력하고
  delayMicroseconds(2);                    // 2 마이크로초가 지나면
  digitalWrite(trigPin, HIGH);                // trigPin에 HIGH를 출력합니다.
  delayMicroseconds(10);                  // trigPin을 10마이크로초 동안 기다렸다가
  digitalWrite(trigPin, LOW);                // trigPin에 LOW를 출력합니다.
  duration = pulseIn(echoPin, HIGH);   // echoPin핀에서 펄스값을 받아옵니다.

  distance = duration * 17 / 1000;          //  duration을 연산하여 센싱한 거리값을 distance에 저장합니다.

  if (distance >= 200 || distance <= 0)       // 거리가 200cm가 넘거나 0보다 작으면
  {
    Serial.println("거리를 측정할 수 없음");   // 에러를 출력합니다.
  }
  else if(distance >= 0 && distance <=7){
    digitalWrite(ledPin_bath, LOW);
    digitalWrite(ledPin_room, LOW);
    Serial.print(distance);
    Serial.println(" cm");
    Serial.println("Passed");    
  }
    else                                               // 거리가 200cm가 넘지 않거나 0보다 작지 않으면
  {
    Serial.print(distance);                        // distance를 시리얼 모니터에 출력합니다.
    Serial.println(" cm");                         // cm를 출력하고 줄을 넘깁니다.
                                                     // distance가 10이면 10 cm로 출력됩니다.
  }
//  delay(100);                                         // 0.5초동안 기다립니다.
//초음파센서 (end)



//압력 값 조건 되면 
  if(force_val1 < 50 && force_val2 != 0 && old_force1 > force_val1+100){
    digitalWrite(Relaypin, LOW);
  }

  old_force1 = force_val1;

 //온습도 측정 데이터 보여줌
  int humidity = dht.readHumidity();
  int temperature = dht.readTemperature();
  
  Serial.print("Humidity: ");  // 문자열 Humidity: 를 출력한다.
  Serial.print(humidity);  // 변수 h(습도)를 출력한다.
  Serial.print("%\t");  // %를 출력한다
  Serial.print("Temperature: ");  // 이하생략
  Serial.print(temperature);
  Serial.println(" C");


  
//습도 높으면 환기 모터 돌아감
  if(humidity  > 75){
    for(angle = 0; angle < 180; angle++) 
    { 
      myservo.write(angle); 
      delay(5); 
    } 
    // now scan back from 180 to 0 degrees
    for(angle = 180; angle > 0; angle--) 
    { 
      myservo.write(angle); 
      delay(5); 
    }
  }

  delay(450);
   
}

1. 사용자가 어플리케이션에서 알람 시간을 설정하면 그 시간에 알람이 울림과 동시에 온수 보일러가 가동된다.

 

2. 침대의 압력센서가 사용자가 침대에 누워있는지를 감지하고 압력이 감지되지 않을 때까지 알람이 울리도록 설계하여 회사나 수업에 지각하는 일을 방지해준다.

 

3. 이런 과정동안 욕조에는 자동으로 데워진 물이 채워지고 일정한 수위가 넘어가면 수도꼭지가 잠겨 더 이상 욕조의 물이 넘치는 일을 방지한다.

 

4. 사용자가 씻는 과정을 마친 후에는 자동으로 화장실의 습도를 측정하여 일정 수준을 넘기면 환풍기가 작동하여 화장실의 습도를 조절해준다.

 

5. 출근 준비가 끝난 사용자는 어플리케이션을 실행하여 메인 화면을 통해 회사 지역의 시간별 날씨를 확인하고 대중교통의 다음 도착시간, 그날 아침의 뉴스 헤드라인을 한번에 확인할 수 있다.

 

6. 또한 오늘 챙겨야 할 물품들을 전날에 미리 어플리케이션에 등록하는 과정을 통해 챙겨야 할 물품들을 다시한번 확인하여 준비물을 까먹고 그냥 출근하는 경우를 예방한다.

 

7. 사용자가 집을 나서기 전, 현관에 위치한 초음파 센서를 통해 사용자가 집을 나가는 것을 확인하면 집 안의 환풍기를 제외한 모든 센서와 조명등이 자동으로 꺼진다.

 

 

728x90
반응형

'공부 > 아두이노' 카테고리의 다른 글

아두이노 압력센서  (0) 2020.07.18
아두이노 온습도 센서  (0) 2020.07.18
아두이노 센서 여러개 사용시 에러  (0) 2020.07.17
블로그 이미지

아상관없어

,
반응형

핀 위치를 바꿔서 꼽아보고 안되면 아두이노 메가 등을 이용하자... 블루투스나 ESP8266같은 와이파이 모듈 사용시 핀 위치 때문에 에러가 많이 난다.

 

(

각각의 센서는 잘되지만 잘 되던 센서들을 한번에 연결하면 특히 오류가 잦다.

그중 블루투스나 와이파이모듈의 RX, TX핀을 어디에 꼽는지에따라 다른 센서가 작동되기도 안되기도 한다 따라서 RX, TX핀 위치를 바꾸어가면서 다른센서가 동작하는지 확인하는 것이 정신건강에 좋다...

 

그리고 가끔 전선의 문제도 잇으니 바꿔서 해보는 것을 추천한다...

 

내가 산 아두이노가 지랄맞은것인진 모르겟으나 여러센서들이 한꺼번에 잘 작동되는것이 자고일어나면 안되는 경우도 많았다....ㅂㄷ..

 

다른 이유론 코딩시 데이터핀 위치를 잘못 지정해주거나 코드상에 오류가 있어 작동을 안하는경우도 있으니 코드도 다시 확인하자.....

(컴퓨터는 거짓말을 하지 않는다... 모두 휴먼탓일뿐이다...)

 

+ 들리는 썰에 의하면 정품 아두이노 UNO보다 짭 UNO보드가 에러를 안일으킨다는 썰이 있다...

)

728x90
반응형

'공부 > 아두이노' 카테고리의 다른 글

아두이노 압력센서  (0) 2020.07.18
아두이노 온습도 센서  (0) 2020.07.18
아두이노 미니 스마트홈  (0) 2020.07.17
블로그 이미지

아상관없어

,
반응형

 

<!DOCTYPE html>
<html>
<style type="text/css">
    canvas { background: blue; }
</style>

<button id = "ButtonX">Rotate X</button>
<button id = "ButtonY">Rotate Y</button>
<button id = "ButtonZ">Rotate Z</button>


<select id = "SelectedImgae" onchange="change();">
    <option value="image1">image1</option>
    <option value="image2">image2</option>
    <option value="image3">image3</option>
</select>


<script id="vertex-shader" type="x-shader/x-vertex">

attribute  vec4 vPosition;
attribute  vec4 vColor;
attribute  vec2 vTexCoord;

varying vec4 fColor;
varying vec2 fTexCoord;

uniform vec3 theta;

void main()
{
    // Compute the sines and cosines of theta for each of
    //   the three axes in one computation.
    vec3 angles = radians( theta );
    vec3 c = cos( angles );
    vec3 s = sin( angles );

    // Remeber: thse matrices are column-major
    mat4 rx = mat4( 1.0,  0.0,  0.0, 0.0,
		    0.0,  c.x,  s.x, 0.0,
		    0.0, -s.x,  c.x, 0.0,
		    0.0,  0.0,  0.0, 1.0 );

    mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
		    0.0, 1.0,  0.0, 0.0,
		    s.y, 0.0,  c.y, 0.0,
		    0.0, 0.0,  0.0, 1.0 );

    mat4 rz = mat4( c.z, s.z, 0.0, 0.0,
		    -s.z,  c.z, 0.0, 0.0,
		    0.0,  0.0, 1.0, 0.0,
		    0.0,  0.0, 0.0, 1.0 );

    fColor = vColor;
    fTexCoord = vTexCoord;
    gl_Position = rz * ry * rx * vPosition;
    gl_Position.z = -gl_Position.z;
}
</script>

<script id="fragment-shader" type="x-shader/x-fragment">

precision mediump float;

varying vec4 fColor;
varying  vec2 fTexCoord;

//shader에서 텍스쳐 데이터에 접근
uniform sampler2D Tex0;


void
main()
{
    gl_FragColor = fColor*(texture2D(Tex0, fTexCoord)*texture2D(Tex1, fTexCoord)*texture2D(Tex2, fTexCoord));
}
</script>

<script type="text/javascript" src="./webgl-utils.js"></script>
<script type="text/javascript" src="./initShaders.js"></script>
<script type="text/javascript" src="./MV.js"></script>
<script type="text/javascript" src="./textureCube1.js"></script>


<body>
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
<img id = "image1" src = "./image1.jpg" ></img>
<img id = "image2" src = "./image2.jpg" ></img>
<img id = "image3" src = "./image3.jpg" ></img>
</body>
</html>

 

"use strict";

var canvas;
var gl;
//삼각형 4개, 사각형 1개(삼각형2개) => 4*3 + 2*4 = 18 개 정점
var numVertices  = 18;

var texSize = 64;


var program;

var pointsArray = [];
var colorsArray = [];
var texCoordsArray = [];

var texture;

//텍스쳐 좌표계
var texCoord = [
    vec2(0, 0),
    vec2(0, 1),
    vec2(1, 1),
    vec2(1, 0)
];

/*
var texCoord2 = [
    vec2(0, 1),
    vec2(0.5, 1),
    vec2(1, 0)
];
*/
/*
    [위에서 쳐다봤을때]
    삼각형 4개 
  1 ㅡㅡㅡㅡㅡㅡ 2
    |*      * |
    |  *  *   |
    |   *4    |  
    | *     * |
   0ㅡㅡㅡㅡㅡㅡ 3
        
*/
var vertices = [
    vec4( -0.5, -0.5,  -0.5, 1.0 ),//0
        vec4( -0.5, -0.5,  0.5, 1.0 ),//1
        vec4(  0.5, -0.5,  0.5, 1.0 ),//2
        vec4(  0.5, -0.5,  -0.5, 1.0 ),//3
        vec4(    0,  0.5,    0, 1.0 )//4
];


var vertexColors = [
    vec4( 0.0, 0.0, 0.0, 1.0 ),  // black
    vec4( 1.0, 0.0, 0.0, 1.0 ),  // red
    vec4( 1.0, 1.0, 0.0, 1.0 ),  // yellow
    vec4( 0.0, 1.0, 0.0, 1.0 ),  // green
    vec4( 0.0, 0.0, 1.0, 1.0 ),  // blue
    vec4( 1.0, 0.0, 1.0, 1.0 ),  // magenta
    vec4( 0.9, 0.9, 0.9, 1.0 ),  // white
    vec4( 0.0, 1.0, 1.0, 1.0 )   // cyan
];

var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = xAxis;
var theta = [45.0, 45.0, 45.0];

var thetaLoc;

function configureTexture( image ) {
//1--------------------------------------------------------------------
	//텍스쳐 생성
    texture = gl.createTexture();
	//사용하기전에 바인딩
    gl.bindTexture( gl.TEXTURE_2D, texture );
	//webGL 애플리케이션은 Y축기준으로 텍스쳐 로딩
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
	//바인딩 후 이미지 데이터 생성 => 이미지를 textImage2D 함수로 넘김
    gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB,
         gl.RGB, gl.UNSIGNED_BYTE, image );
       //밉맵 생성
    gl.generateMipmap( gl.TEXTURE_2D );
	//텍스쳐 필터 지정
    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
                      gl.NEAREST_MIPMAP_LINEAR );
    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
    gl.uniform1i(gl.getUniformLocation(program, "texture"), 0);
   
//--------------------------------------------------------------------
}

function quad(a, b, c, d) {

     pointsArray.push(vertices[a]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[0]);

     pointsArray.push(vertices[b]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[1]);

     pointsArray.push(vertices[c]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[2]);

     pointsArray.push(vertices[a]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[0]);

     pointsArray.push(vertices[c]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[2]);

     pointsArray.push(vertices[d]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[3]);
}

function triple(a, b, c) {
     pointsArray.push(vertices[a]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[0]);

     pointsArray.push(vertices[b]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[1]);

     pointsArray.push(vertices[c]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[2]);

} 

function colorCube()
{
   triple( 0, 4, 1);
   triple( 3, 4, 0 );
   triple( 2, 4, 3);
   triple( 1, 4, 2 );
   quad( 0, 1, 2,3 );
}

function chageSelectedValue(){
    var SelectedImg = document.getElementById("Selected Imgae");
    var selectedValue = SelectedImg.options[SelectedImg.selectedIndex].value;
  
}


window.onload = function init() {

    canvas = document.getElementById( "gl-canvas" );

    gl = WebGLUtils.setupWebGL( canvas );
    if ( !gl ) { alert( "WebGL isn't available" ); }

    gl.viewport( 0, 0, canvas.width, canvas.height );
    gl.clearColor( 1.0, 1.0, 1.0, 1.0 );

    gl.enable(gl.DEPTH_TEST);

    //
    //  Load shaders and initialize attribute buffers
    //
    program = initShaders( gl, "vertex-shader", "fragment-shader" );
    gl.useProgram( program );

    colorCube();


    var cBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );

    var vColor = gl.getAttribLocation( program, "vColor" );
    gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vColor );

    var vBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );

    var vPosition = gl.getAttribLocation( program, "vPosition" );
    gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vPosition );

    var tBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW );

    var vTexCoord = gl.getAttribLocation( program, "vTexCoord" );
    gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vTexCoord );






    change();

    thetaLoc = gl.getUniformLocation(program, "theta");

    document.getElementById("ButtonX").onclick = function(){axis = xAxis;};
    document.getElementById("ButtonY").onclick = function(){axis = yAxis;};
    document.getElementById("ButtonZ").onclick = function(){axis = zAxis;};

    render();

}

function change(){

    var SelectedImg = document.getElementById("SelectedImgae");
    var id = SelectedImg.options[SelectedImg.selectedIndex].value;

    var image = document.getElementById(id);
    configureTexture( image );
}



var render = function(){
    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    theta[axis] += 2.0;
    gl.uniform3fv(thetaLoc, flatten(theta));
    gl.drawArrays( gl.TRIANGLES, 0, numVertices );
    requestAnimFrame(render);
}

참고: 만약 로컬에서 이걸 실행하는 경우 WebGL에서 이미지를 로드할 수 있도록 하기 위해 간단한 웹 서버가 필요합니다 => 가장 간단하게 만들 수 있는 웹 서버인 “Web Server for Chrome”

728x90
반응형

'공부 > WebGL' 카테고리의 다른 글

WebGL 피라미드  (0) 2020.07.17
WebGL sierpinski carpet  (0) 2020.07.17
블로그 이미지

아상관없어

,

WebGL 피라미드

공부/WebGL 2020. 7. 17. 02:33
반응형

<html>

<html>

<script id="vertex-shader" type="x-shader/x-vertex">

attribute  vec4 vPosition;
attribute  vec4 vColor;
varying vec4 fColor;

uniform vec3 theta;

void main() 
{
    // Compute the sines and cosines of theta for each of
    //   the three axes in one computation.
    vec3 angles = radians( theta );//각도입력
    vec3 c = cos( angles );//cos
    vec3 s = sin( angles );//sin

    // Remeber: thse matrices are column-major
    //x축 회전인데, column major로 표현
    mat4 rx = mat4( 1.0,  0.0,  0.0, 0.0,
		    0.0,  c.x,  s.x, 0.0,
		    0.0, -s.x,  c.x, 0.0,
		    0.0,  0.0,  0.0, 1.0 );
    //y축 회전인데, column major로 표현
    mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
		    0.0, 1.0,  0.0, 0.0,
		    s.y, 0.0,  c.y, 0.0,
		    0.0, 0.0,  0.0, 1.0 );

    //z축 회전인데, column major로 표현
    mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
		    s.z,  c.z, 0.0, 0.0,
		    0.0,  0.0, 1.0, 0.0,
		    0.0,  0.0, 0.0, 1.0 );

    fColor = vColor;
    gl_Position = rz * ry * rx * vPosition;
    //x, y, z순으로 곱해져야
    //새로운 vPosition
} 
</script>

<script id="fragment-shader" type="x-shader/x-fragment">

precision mediump float;
   
varying vec4 fColor;

void
main()
{
    gl_FragColor = fColor;
}
</script>

<script type="text/javascript" src="webgl-utils.js"></script>
<script type="text/javascript" src="initShaders.js"></script>
<script type="text/javascript" src="MV.js"></script>
<script type="text/javascript" src="cube.js"></script>

<body>
<canvas id="gl-canvas" width="512"" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
   
<br/>

<button id= "xButton">Rotate X</button>
<button id= "yButton">Rotate Y</button>
<button id= "zButton">Rotate Z</button>

</body>
</html>

 

js

//=====================================================================
//변수들 선언
//=====================================================================
var canvas;
var gl;

//삼각형 4개, 사각형 1개(삼각형2개) => 4*3 + 2*4 = 18 개 정점
var NumVertices  = 18;

//정점을 저장하는 배열
var points = [];

//색상을 저장하는 배열
var colors = [];

//x, y, z축
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;

//기본축
var axis = 0;

//x, y, z만큼 각도
var theta = [ 0, 0, 0 ];

var thetaLoc;
//=====================================================================
window.onload = function init()// 콜백함수, onload = 모든코드가 로드된 후 시작할 위치를 지정
//모든 action은 init()과 render()같은 함수 안에 잇는데, 
//onload 이벤트가 발생할때, init()함수를 실행하게함.
{
    canvas = document.getElementById( "gl-canvas" );
    // 캔버스를 읽어옴, getElementById 함수로 "gl-canvas"를 불러옴

    gl = WebGLUtils.setupWebGL( canvas );
    // 불러온 canvas를 인자로 넘겨, WebGL코드를 설정해줌
    if ( !gl ) { alert( "WebGL isn't available" ); }

    //함수 실행
    colorCube();
    //=====================================================================
    gl.viewport( 0, 0, canvas.width, canvas.height );//크기
    gl.clearColor( 1.0, 1.0, 1.0, 1.0 );//배경색
    //depth buffer의 내용에 따라 fragment의 깊이 값을 테스트합니다.
    //OpenGL은 depth test를 수행하고 이 테스트가 통과되면 이 depth buffer는 새로운 깊이 값으로 수정됩니다. 
    //이 테스트가 실패한다면 해당 fragment는 폐기됩니다.
    gl.enable(gl.DEPTH_TEST);
    //=====================================================================


    //=====================================================================
    //  Load shaders and initialize attribute buffers
    //=====================================================================
    //GPU에 넘겨줄 Program 객체
    //initShaders사용하여 shader 로드, 컴파일, 링크하여 Program객체 생성
    var program = initShaders( gl, "vertex-shader", "fragment-shader" );
    gl.useProgram( program );
    
    //-------------------------------------------------------------------
    //color 버퍼를 만들고 컬러를 넣음
    var cBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );

    var vColor = gl.getAttribLocation( program, "vColor" );
    gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vColor );
    //-------------------------------------------------------------------

    //-------------------------------------------------------------------
    //data를 넣을 버펄르 만들고 데이터를 줌
    var vBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
    

    var vPosition = gl.getAttribLocation( program, "vPosition" );
    gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vPosition );
    //------------------------------------------------------------------- 

    //getUniformLocation함수로 theta값 가져옴.
    thetaLoc = gl.getUniformLocation(program, "theta");
     
    //=====================================================================


    //=====================================================================
    //버튼 이벤트 리스너 (축에 버튼에 해당하는 축을 넣음)
    //=====================================================================
    document.getElementById( "xButton" ).onclick = function () {
        axis = xAxis;
    };
    document.getElementById( "yButton" ).onclick = function () {
        axis = yAxis;
    };
    document.getElementById( "zButton" ).onclick = function () {
        axis = zAxis;
    };
    //=====================================================================   


    render();
}

//=====================================================================   
function colorCube()
{
    //피라미드는 삼각형 4개, 정육면체 1개
   triple( 1, 0, 4 );
   triple( 0, 3, 4 );
   triple( 3, 2, 4 );
   triple( 1, 4, 2 );
   quad( 0, 4, 7, 3 );
}
//=====================================================================   



//=====================================================================   
//삼각형을 그려줌, abc인자로
//=====================================================================   
/*
    [위에서 쳐다봤을때]
    삼각형 4개 
  1 ㅡㅡㅡㅡㅡㅡ 2
    |*      * |
    |  *  *   |
    |   *4    |  
    | *     * |
   0ㅡㅡㅡㅡㅡㅡ 3
        
*/
//사각뿔의 꼭지 위 점과, 밑 사각형의 점로 삼각형을 그림
function triple(a, b, c){
    //삼각형 4개 정점
    var vertices = [
        vec4( -0.5, -0.5,  -0.5, 1.0 ),//0
        vec4( -0.5, -0.5,  0.5, 1.0 ),//1
        vec4(  0.5, -0.5,  0.5, 1.0 ),//2
        vec4(  0.5, -0.5,  -0.5, 1.0 ),//3
        vec4(    0,  0.5,    0, 1.0 )//4
    ];
    var vertexColors = [
        [ 0.0, 0.0, 0.0, 1.0 ],  // black
        [ 1.0, 0.0, 0.0, 1.0 ],  // red
        [ 1.0, 1.0, 0.0, 1.0 ],  // yellow
        [ 0.0, 1.0, 0.0, 1.0 ],  // green
        [ 0.0, 0.0, 1.0, 1.0 ],  // blue
        [ 1.0, 0.0, 1.0, 1.0 ],  // magenta
        [ 0.0, 1.0, 1.0, 1.0 ],  // cyan
        [ 1.0, 1.0, 1.0, 1.0 ]   // white
    ];

    
    //삼각형이므로 인자를 3개 받음
    var indices = [ a, b, c ];

    for ( var i = 0; i < indices.length; ++i ) {
        //vertices[a], vertices[b], vertices[c]를 넣음
        points.push( vertices[indices[i]] );
            //평면의 색을 그라데이션효과 처럼 해줌        
        //colors.push( vertexColors[indices[i]] );
    
        //평면이 모두 같은 색(vertexColors[b]으로 되게 해줌 => 2번째 인자를 안겹치게 했음
        colors.push(vertexColors[b]);
        
    }
}
//=====================================================================   







//=====================================================================   
//4개의 인자로, abc, acd 사각형을 그려줌
//=====================================================================   
/*
[밑에서 쳐다봤을때] 
정육면체1개(삼각형 2개) 
        
   4ㅡㅡㅡㅡㅡㅡ7
    |         |
    |         |
    |         |  
    |         |
   0ㅡㅡㅡㅡㅡㅡ3
 =>예제 cube코드를 가져와 사용.       
*/
function quad(a, b, c, d) 
{
    //=> ppt그림 참고함
    var vertices = [
        vec4( -0.5, -0.5,  0.5, 1.0 ),//0
        vec4( -0.5,  0.5,  0.5, 1.0 ),//1
        vec4(  0.5,  0.5,  0.5, 1.0 ),//2
        vec4(  0.5, -0.5,  0.5, 1.0 ),//3
        vec4( -0.5, -0.5, -0.5, 1.0 ),//4
        vec4( -0.5,  0.5, -0.5, 1.0 ),//5
        vec4(  0.5,  0.5, -0.5, 1.0 ),//6
        vec4(  0.5, -0.5, -0.5, 1.0 )//7
    ];

    var vertexColors = [
        [ 0.0, 0.0, 0.0, 1.0 ],  // black
        [ 1.0, 0.0, 0.0, 1.0 ],  // red
        [ 1.0, 1.0, 0.0, 1.0 ],  // yellow
        [ 0.0, 1.0, 0.0, 1.0 ],  // green
        [ 0.0, 0.0, 1.0, 1.0 ],  // blue
        [ 1.0, 0.0, 1.0, 1.0 ],  // magenta
        [ 0.0, 1.0, 1.0, 1.0 ],  // cyan
        [ 1.0, 1.0, 1.0, 1.0 ]   // white
    ];

    
    var indices = [ a, b, c, a, c, d ];

    for ( var i = 0; i < indices.length; ++i ) {
        //vertices[a] ~ [b] ~ [c] ~ [a] ~ [c] ~[d]를 넣음
        points.push( vertices[indices[i]] );
        //colors.push( vertexColors[indices[i]] );
    
        // 위 삼각형들의 색상과 겹치지 않게 하기위해 6번째 색 사용 
        colors.push(vertexColors[5]);
        
    }
}
//=====================================================================   








//=====================================================================   
function render()
{
    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    //aixs축 기준으로 각도 2도 만큼
    theta[axis] += 2.0;
    //uniform 변수로 theta 전달, vertex shader가 그릴수 있게 해줌.
    gl.uniform3fv(thetaLoc, theta);
    
    /* 밑의 코드와 동일 코드
    for(i = 0; i< points.length; i = i+3){ 
        gl.drawArrays( gl.TRIANGLES, i, 3);
    }*/
    gl.drawArrays( gl.TRIANGLES, 0, NumVertices );

    requestAnimFrame( render );
    //render 함수를 애니메이션으로 실행
}
//=====================================================================   

 

 

옆면의 삼각형 4개와 밑면의 사각형 하나가 필요하다. 밑면의 사각형은 2개의 삼각형으로 만들어지므로, 결국 6개의 삼각형으로 구성된다. 따라서 Numvertex18개가 된다.

 

 

꼭지점을 위 그림처럼 잡아주었고 그리고 순서를 0,1,2,3,4로주어 그림을 그렸다.

colorCube함수에 삼각형을 그려주는 triple함수를 구현하여, 삼각형과 사각형을 따로 구분 지어 그렸다.

728x90
반응형

'공부 > WebGL' 카테고리의 다른 글

WebGL 피라미드 텍스쳐  (0) 2020.07.17
WebGL sierpinski carpet  (0) 2020.07.17
블로그 이미지

아상관없어

,
반응형

 

carpet.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>2D Sierpinski carpet LAST</title>

<!--Vertex Shader에 전송하는 변수 'v'Position-->
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;

void
main()
{
    gl_Position = vPosition;
}
</script>

<!--fragment shader-->
<!--정밀도는 medium으로-->
<!--X => (배경색을 빨강으로 하고 안의 네모를 힌색으로 구현)-->
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;

void
main()
{
    gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
}
</script>


<script type="text/javascript" src="webgl-utils.js"></script>
<script type="text/javascript" src="initShaders.js"></script>
<!--
gasket2.js 에서 사용할 라이브러리, Web GL구동을 위한 기본적인 라이브러리
webgl-utils.js = 웹사이트의 Common 디렉토리에 있는 WebGL context를 설정하는 표준 유틸리티
initShaders.js = shader를 읽고, 컴파일하고, 링크하는 JS와 WebGL 코드
-->
<script type="text/javascript" src="MV.js"></script>
<!--수학함수 벡터관리 함수, 자체 행렬 벡터 패키지(책의 저자가 제공)-->
<script type="text/javascript" src="carpet.js"></script>
<!-- 실행 하려는 프로그램, 응용 프로그램 파일-->
</head>   

<body>
	<!-- 캔버스 정의-->
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>

carpet.js

"use strict";

var canvas;
var gl;
var i;
var points = [];

var NumTimesToSubdivide = 7;



//onload함수로 시작함
window.onload = function init()// 콜백함수, onload = 모든코드가 로드된 후 시작할 위치를 지정
{
    canvas = document.getElementById( "gl-canvas" );
    // 캔버스를 읽어옴, getElementById 함수로 "gl-canvas"를 불러옴

    gl = WebGLUtils.setupWebGL( canvas );
    // 불러온 canvas를 인자로 넘겨, WebGL코드를 설정해줌

    if ( !gl ) { alert( "WebGL isn't available" ); }
    //예외처리

    //
    //  Initialize our data 
    //

    // 네 점 초기ㅗ하

    var vertices = [
        vec2(-1,-1),//a
        vec2(-1, 1),//b
        vec2(1, 1),//c
        vec2(1, -1)//d
    ];
    /*
     b     c
     *-----* 
     |   * |
     | *   |
     *-----*
     a     d

    */
    divideTriangle(vertices[0], vertices[1], vertices[2], vertices[3], NumTimesToSubdivide);
    

    /*==========================================================*/
    //WebGL 기본 코드 
    //
    //  Configure WebGL
    //
    gl.viewport( 0, 0, canvas.width, canvas.height );
    gl.clearColor( 1.0, 1.0, 1.0, 1.0  ); // X => (//색상 흰색으로)
    /*==========================================================*/


    /*====================================================================*/
    //  Load shaders and initialize attribute buffers
    //GPU에 넘겨줄 Program 객체
    //initShaders사용하여 shader 로드, 컴파일, 링크하여 Program객체 생성
    var program = initShaders( gl, "vertex-shader", "fragment-shader" );
    gl.useProgram( program );
    /*====================================================================*/


    /*========================================================================================*/
    // Load the data into the GPU
    //Vertex buffer 객체를 GPU에 로드함
    //버퍼를 만들어서 data를 줌성
    var bufferId = gl.createBuffer();//버퍼 생성
    gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );//bufferId에 binding
    gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );//데이터를 버퍼에
    //flatten() => js배열을 float32 배열로 변환 (OpenGL - JS간 배열 해석이 다르므로 row -> column)
    /*========================================================================================*/


    /*========================================================================================*/
    // Associate out shader variables with our data buffer
    //프로그램 내 변수와 shader변수를 연결해야함 => 버퍼내 이름, 타입, 위치가 필요
    //vPosition 변수에 실어 보냄, vPosition => 그 변수의 위치를 받아오겠다
    var vPosition = gl.getAttribLocation( program, "vPosition" );//getAttributeLocation = 위치
    gl.vertexAttribPointer( vPosition, 2, gl.FLOAT, false, 0, 0 );//vertex 속성, 2차원
    gl.enableVertexAttribArray( vPosition );
    /*========================================================================================*/


    //랜더링 = 그림을 그려줌
    render();
};

/*==========================*/
//WebGL은 삼각형만 디스플레이함/
/*==========================*/

//스택에 4개 넣고
//기본요소 TRIANGLE_FAN를 사용, 인자 4개
function triangle( a, b, c, d )
{
    points.push( a, b, c, d );
}


// X => (/* 배경을 빨간색으로 지정하고 안의 사각형을 힌색으로 지정해 안의 사각형만 그려주면됌*/)
//사각형을 그려줌, 중간 공간은 안그림
function divideTriangle( a, b, c, d, count )
{

    // check for end of recursion
    //더이상 쪼갤 필요가 없을때 
   if ( count === 0 ) {
        triangle( a, b, c, d);
    }

   else {
        //위
        var bc1 = mix( b, c, 1/3);
        var bc2 = mix( b, c, 2/3);

        //왼쪽
        var ab1 = mix( a, b, 1/3);
        var ab2 = mix( a, b, 2/3);

        //오른쪽
        var cd1 = mix( c, d, 1/3);
        var cd2 = mix( c, d, 2/3);

        //밑
        var ad1 = mix( a, d, 1/3);
        var ad2 = mix( a, d, 2/3);

        //중간 사각형 vertex
        var ma = mix( ab1, cd2, 1/3);
        var mb = mix( ab2, cd1, 1/3);
        var mc = mix( ab2, cd1, 2/3);
        var md = mix( ab1, cd2, 2/3);
        //=> 중간에 있는 4개 vertex를 사용해서 삼각형 두개로 사각형 만듬  
        //최종적 실행은 triangle(ma, mb, mc, md) => 각 사각형 마다 해주면됌      


        /*

            b  bc1 bc2  c
            *---*---*---*
            | 1 | 2 | 3 |
         ab2*---*---*---*cd1
            | 4 | 5 | 6 |
         ab1*---*---*---*cd2
            | 7 | 8 | 9 |
            *---*---*---* 
            a  ad1 ad2  d

        */
         --count;


        divideTriangle(ab2, b, bc1, mb, count);  //1번사각형
        divideTriangle(mb, bc1, bc2, mc, count); //2번사각형
        divideTriangle(mc, bc2, c, cd1, count);  //3번사각형
        divideTriangle(ab1, ab2, mb, ma, count); //4번사각형

        //중간 사각형은그리지 않으므로
        //divideTriangle(ma, mb, mc, md, count); //5번사각형 

        divideTriangle(md, mc, cd1, cd2, count); //6번사각형
        divideTriangle(a, ab1, ma, ad1, count);  //7번사각형
        divideTriangle(ad1, ma, md, ad2, count); //8번사각형
        divideTriangle(ad2, md, cd2, d, count);  //9번사각형
    }
}

function render()
{
    gl.clear( gl.COLOR_BUFFER_BIT );
    for(i = 0; i< points.length; i = i+4){ 
        gl.drawArrays( gl.TRIANGLE_FAN, i, 4);
    }
    //삼각형 두개 로 나눠서 위 삼각형 아래 삼각형 따로 함수 구현하지 않기 위해 Triganles 대신 Triangles_fan 사용
}

 

728x90
반응형

'공부 > WebGL' 카테고리의 다른 글

WebGL 피라미드 텍스쳐  (0) 2020.07.17
WebGL 피라미드  (0) 2020.07.17
블로그 이미지

아상관없어

,
반응형

mysh.h

//header for myshell by 이창민, ckdals0115@naver.com

//mysh.h

#include<unistd.h>

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<wait.h>

#include<sys/stat.h>

#include<sys/types.h>

#include<fcntl.h>

#include<signal.h>

#include<errno.h>

#define MAX 100

//static int child_pid = 0;

//static int COUNT = 0;

//static char* COMMAND_PATH = "Desktop/Sys/mysh/";

void redirection_com(char** commands, int i);

void background_com(char** commands, int i);

char** get_tokens(char* CommandLine);

void execute_com(char** command);

 

mysh.c

//myshell by 이창민, ckdals0115@naver.com
//mysh.c 
#include"mysh.h"
void main(){
	write(STDOUT_FILENO,"+------------------------------------------------------------------------------------+\n",88);
	write(STDOUT_FILENO,"|MYSHELL                                                                             |\n",88);
	write(STDOUT_FILENO,"|------------------------------------------------------------------------------------|\n",88);
	write(STDOUT_FILENO,"|QUIT : quit                                                                         |\n",88);
	write(STDOUT_FILENO,"+------------------------------------------------------------------------------------+\n",88);

	while(1){
		//write시 쓰레기값 없게 초기화
		char CommandLine[MAX]={0};
		char PWD[MAX]={0};
		char** command;
		int read_size;
		int errno;
		/*char *getcwd(char *buf, int maxlen); => get pwd "unistd.h*/
		getcwd(PWD,MAX);
 	/////////////////////////////////////////////////////////////////
	//화면에 출력, write가 printf보다 빠르므로 write를 써봣음..
		write(STDOUT_FILENO, "@myshell:~", 20);
		write(STDOUT_FILENO, PWD, MAX);
		write(STDOUT_FILENO, "$ ",3);
	/////////////////////////////////////////////////////////////////
	//읽기
		/*입력받은 커맨드 command로 읽음*/
		read_size = read(STDIN_FILENO, CommandLine, MAX);
		//input enter
		if(read_size == 1){
			continue;}
	////////////////////////////////////////////////////////////////
	//명령어 구분하고 실행
		command = get_tokens(CommandLine);
		if(!strcmp(command[0],"quit")){
			printf("+------------------------------------------------------------------------------------+\n");
			printf("|BASH                                                                                |\n");
			printf("+------------------------------------------------------------------------------------+\n");
			exit(1);}
		else{
			execute_com(command);
		}
		
	}
}

mysh_funcs.c

//functions for myshell by 이창민, ckdals0115@naver.com
//mysh_funcs.c
/*
token구하기
명령수행
-shell bulitin
-/bin
-redirection
-background
 */
#include"mysh.h"
/////////////////////////////////////////////////////////////////////////////////////
////////CommandLine 쪼갬
char** get_tokens(char* CommandLine) {
	char **tokens;//토큰들을 저장할 배열
	char *token;
	int COUNT=0;
	//\n 대신 \0넣음
	CommandLine[strlen(CommandLine) - 1] = '\0';
	//토큰 저장할 배열 크기
	tokens = malloc((sizeof(char*))*MAX);
	//" "을 구분자로 자름
	token = strtok(CommandLine, " ");
	while(token != NULL){
		//\0포함해야하므로 +1
		tokens[COUNT] =malloc(strlen(token)+1);
		//동적할당 후 내용복사 
		strncpy(tokens[COUNT], token, strlen(token)+1);
		token = strtok(NULL, " ");
		COUNT++;
	}
	//토큰들 입력 끝나면 null
	tokens[COUNT] = NULL;
	return tokens;
}
//////////////////////////////////////////////////////////////////////////////////////
/////명령을 받으면 수행 
void execute_com(char **commands){
	int fork_process;
	int status;
	int i=0;
	char *dir;
	///////////////////////////////////////////////
	/////////shell builtin command  
	if(!strcmp(commands[0], "cd")){
		if(commands[1] == NULL){
			printf("USEAGE : cd directory\n");
			}
		chdir(commands[1]);
	}
	else if(!strcmp(commands[0], "pwd")){
		printf("Present Working Directory: %s\n",getcwd(dir, MAX));
	}
	///////////////////////////////////////////////
	///////////저장되어있는 명령어(/bin안에 존재)
	else {
		if((fork_process = fork())==0){
		//execv'P' 는 PATH에 등록된 모든 디렉토리에 있는 프로그램을 실행
			//명령어 끝까지 읽어서 각각 상황에 따라 실행
			while(commands[i]){
				if(!strcmp(commands[i],">")){
					redirection_com(commands, i);
				}
				else if(!strcmp(commands[i],"&")){
					background_com(commands, i);
				}
				i++;
			}
			//잘못된 commands[0]가 들어오면 -1 반환함
			if(execvp(commands[0],commands)==-1){
				printf("%s : command not found\n",commands[0]);
				exit(1);
			}
		}
		else if(fork_process < 0){
			printf("fork error\n");
			exit(1);
		}
		else
			wait(&status);
	}
}

//////////////////////////////////////////////////////////////////////
///////////명령어에 리다이렉션이 있을경우 수행
//ex) cat a.txt > b.txt
void redirection_com(char** commands, int i){
	char* to = commands[i+1];
	char* from = commands[i-1];
	int to_fd;

	to_fd = open(to, O_WRONLY | O_CREAT, 0641);
	if(to_fd < 0){
		printf("open error\n");
		exit(1);
	}
	//STDOUT_FILENO이 to_fd를 가리키게함
	dup2(to_fd, STDOUT_FILENO);
	//>자리를 NULL로
	commands[i] = NULL;
	//명령어 수행
	if(execvp(commands[0], commands)==-1){
		printf("No such command : %s\n",commands[0]);
                exit(1);
	}
}
/////////////////////////////////////////////////////////////////////////
////////명령어에 &이 있을경우 background processing 수행
void background_com(char** commands, int i){
	commands[i]=NULL;
	int fork_process;
	if((fork_process = fork())==0){
		if(execvp(commands[0], commands)==-1){
                printf("No such command : %s\n",commands[0]);
                exit(1);
		}
	}
	else if(fork_process<0){
		printf("fork error\n");
		exit(1);
	}
	//기다리지 않음
	else{
		exit(1);
	}
};

while1.c (단순 무한 루프)

#include<stdio.h>
int main(){
	while(1){
	}
	return 0;
}

Makefile

mysh: mysh.o mysh_funcs.o
gcc -o mysh mysh.o mysh_funcs.o

mysh.o: mysh.h mysh.c
gcc -c mysh.c

mysh_funcs.o: mysh.h mysh_funcs.c
gcc -c mysh_funcs.c

 

현재 ~디렉토리 $를 해주기 위해 getcwd를 사용하여 현재 디렉토리를 가져와 터미널에 출력하였다.

read systemcall을 사용하여 STDIN을 읽었다. 그리고 만약 엔터 \n만 치게된다면 다시 커맨드를 입력받을 수 있게 하였다.

명령어가 들어오면 execute_com를 실행하여 명령어를 실행하게 하였고, quit를 입력하면 myshell이 종료되게 하였다.

 

execute_com을 하려면 일단 입력받은 커맨드를 쪼개서 구분을 하여 명령을 처리해야한다. 따라서 get_tokens라는 토큰을 얻는 함수를 생성하였다. strtok함수를 이용하여 “ ”을 구분자로 하여 token화 하였다.

 

커멘드를 token으로 쪼개어 명령을 수행하는데, shell builtin 명령어들은 /bin에 저장되어있는 것이 아니라 bash가 동작할 때 수행하므로 각 명령어에 맞는 함수들을 사용하여 구현하였다.

shell builtin명령어들은 종류가 많이 있지만 각각 경우들을 비교하려면 수행시간이 길어지므로 cdpwd만 구현을 하였다.

 

따라서, strcmp함수를 사용하여 shell builtin명령어가 들어오면 builtin명령어인지 구분하여 실행을 한다.

 

그 외의 명령어들은 /bin에 있으므로 execvp를 사용하여 명령어를 실행한다. 환경변수 path에 디렉토리가 있으면 파일명만 입력하면 되므로 commands[0]을 인자로 넘겨준다.

 

리다이렉션의 경우, “from_file > to_file”의 형태이므로 STDOUT_FILENOto_file fd를 가리키게 한다.

그리고 “>” 앞의 명령어들을 실행하여 to_file에 그 결과들이 수행되게 한다.

 

백그라운드의 경우, fork를 한 후 부모프로세스는 자식프로세스를 wait하지 않게 하여 자식 프로세스가 백그라운드 프로세스로 돌아가도록 한다.

 

나머지 잘못된 사용을 하였을 시 잘못되었다고 예외처리들을 해주었다.

 

bashbuiltin 명령어들을 모두 구현하기 위해선 모든 builtin 명령어에 해당하는지 검사를 하고, 또 그에 따른 적절한 함수들을 사용해야하므로 코드가 길어지고 명령어 수행시간이 길어질 것 같았다.

따라서 cd, pwd와 같은 간단한 명령어만 수행하였다.

여기서 굳이 shell에서 builtin 명령어, 그 외 명령어로 구분지어 하나는 파일로 저장을 하고 하나는 쉘 내부에서 작동하게 하였는지 궁금하여 찾아보니, builtin 명령어들은 자주 사용되어 파일로 디스크에 저장해두면 매번 디스크에서 불러와야하므로 효율을 높이기 위해 램에 상주시키는 것을 알게 되었다.

728x90
반응형
블로그 이미지

아상관없어

,
반응형

 

//mycp app by changmin, ckdals0115@naver.com

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define MAX 64

void main(int argc,char* argv[]){

	int original, copy, r_size;
	char buf[MAX];
	struct stat attribute;//stat 구조체선언  mode_t st_mode로 파일 권한을 가져오기위해 

	//쓰기잘못	
	if(argc != 3){
		printf("Wrong useage! USAGE : %s \"original_file\" \"copy_file\" \n",argv[0]);
		exit(-1);}
	//orignal 파일 열기
	original = open(argv[1],O_RDONLY);
	//파일 open 실패시
	if(original < 0){
		printf("can't open file\n");
		exit(-1);}
	
	if(stat(argv[1], &attribute)==-1){//original file 속성가져옴 실패시 에러
		printf("getting attribute error\n");
		exit(-1);}
	
	
	mode_t original_permisson = attribute.st_mode;//original의 st_mode를 가져옴
	



	copy = open(argv[2],O_WRONLY|O_CREAT|O_EXCL,original_permisson);//쓰기로 읽고 권한을 original파일의 권한을 줌
	//파일 open 실패시
	if(original < 0){
                printf("can't open file\n");
                exit(-1);}
	//파일끝까지 읽고 씀
	while((r_size = read(original,buf,MAX)) >0){
		write(copy,buf,r_size);
	}
}
728x90
반응형
블로그 이미지

아상관없어

,
반응형

www.google.com/maps/d/edit?mid=1STNkMbZbYZUpAut7cfg_xItN5yRqHkBt&usp=sharing

728x90
반응형

'기타 > 여행 지도 공유(구글맵)' 카테고리의 다른 글

도쿄 지도  (0) 2020.07.16
블라디보스토크 지도  (0) 2020.07.16
제주도 지도  (0) 2020.07.16
괌 지도  (0) 2020.07.16
블로그 이미지

아상관없어

,
반응형

www.google.com/maps/d/edit?mid=1tOOrkbGAebK1Z8trGOIdFouVbsY&usp=sharing

728x90
반응형

'기타 > 여행 지도 공유(구글맵)' 카테고리의 다른 글

오사카 지도  (0) 2020.07.16
블라디보스토크 지도  (0) 2020.07.16
제주도 지도  (0) 2020.07.16
괌 지도  (0) 2020.07.16
블로그 이미지

아상관없어

,
반응형

www.google.com/maps/d/edit?mid=1CZKN0355ykP1_FRHKYy5mxR6L7cZ8FCT&usp=sharing

728x90
반응형

'기타 > 여행 지도 공유(구글맵)' 카테고리의 다른 글

오사카 지도  (0) 2020.07.16
도쿄 지도  (0) 2020.07.16
제주도 지도  (0) 2020.07.16
괌 지도  (0) 2020.07.16
블로그 이미지

아상관없어

,
반응형

www.google.com/maps/d/edit?mid=1q_DFwZ124alhrhalxabfZaYy816TPqoZ&usp=sharing

728x90
반응형

'기타 > 여행 지도 공유(구글맵)' 카테고리의 다른 글

오사카 지도  (0) 2020.07.16
도쿄 지도  (0) 2020.07.16
블라디보스토크 지도  (0) 2020.07.16
괌 지도  (0) 2020.07.16
블로그 이미지

아상관없어

,
반응형

www.google.com/maps/d/edit?mid=1Z0ydP650Fr0XxX-ebqMbHCZFmu1mM7kj&usp=sharing

728x90
반응형

'기타 > 여행 지도 공유(구글맵)' 카테고리의 다른 글

오사카 지도  (0) 2020.07.16
도쿄 지도  (0) 2020.07.16
블라디보스토크 지도  (0) 2020.07.16
제주도 지도  (0) 2020.07.16
블로그 이미지

아상관없어

,
반응형

Boot Sector의 크기는 2 Sector = 1KB(0x400)이므로 Super Block의 위치는 0x400부터 시작한다.

해당위치로 이동하면,

Log Block Size( 블록 크기 ) = 0x2000, Inode Per Group( 각 블록그룹에 속한 inode ) = 0xef53, Block Per Group( 각 블록 그룹에 속한 block ) = 0x8000을 얻을 수 있다.

Ext2에서 Root inode number2이다. 따라서 (inode number – 1)/block per group을 하면 Rootinode가 속한 그룹은 0번임을 알 수 있다. 그리고 (inode number -1)%block per group을 하여 Root index1임을 알 수 있다.

그리고 Root안의 데이터를 보기위해 Group Descriptor Table을 보아 Group 0 inode Table 시작위치를 얻는다.

 

첫 번째 Group Descriptor Tableramdisk1블록(4KB = 0x1000) 이후부터 시작하므로 해당 위치로 이동하면

각 그룹의 inode Table을 구하면

(단위 : block)

Group 0 = 0x23

Group 1 = 0x8023

Group 2 = 0x10002

Group 3 = 0x18023

이다.

 

Root가 속한 Group 0inode Table에서 1번째 inode를 찾는다. ( Inode의 크기는 0x100byte, index = 1 )

첫번째 블록 포인터인 0x223000을 찾아서 데이터 영역으로 이동을 한다.

Record len으로 디렉토리 엔트리의 크기를 알아내고, file type으로 디렉토리를 찾고, 이름을 얻는다. 그중 32153”6/82”에 해당하는 6번 디렉토리의 inode를 찾는다.

6번 디렉토리 inode number = 0x6066

속한 Block Group = (0x6066 – 1)/0x2000 = 3

Inode Table Index = (0x6066 – 1)%0x2000 = 101

 

6번 디렉토리가 Block Group 3 inode Table101번째에 있음을 알 수 있다.

 

Block Group 3inode Table에서 101번째 inode로 이동을 한다.

=>0x18029600

Block pointer 0번을 얻고 이동을 한다.

=>0x8458000

6번 디렉토리가 있음을 확인할 수 있다.

 

학번의 끝이 682이므로 0x18029600에서 82번 뒤로 이동을 한다.

=>0x1802e800

Block Pointer 0 = 0x84aa000

Block Pointer 1 = 0x107ba000

Block Pointer 2 = 0x107d2000

 

Indirect Block Pointer 0 = 0x10204000

을 얻을 수 있다.

 

해당 블록의 위치로 이동을 하면 다음의 그림과 같이 데이터를 찾을 수 잇다.

 

 

마지막 indirect block pointer13번째 blockinode를 찾아내고 이동하여 데이터를 찾았다.

728x90
반응형

'공부 > 운영체제&시스템프로그래밍' 카테고리의 다른 글

New Architectural state structure  (0) 2021.06.21
myshell  (0) 2020.07.16
mycp  (0) 2020.07.16
블로그 이미지

아상관없어

,