[Java/SWT] 그래픽스 컨텍스트 (Graphics Context)

by Blogger 하얀쿠아
2012. 12. 7. 21:59 소프트웨어 Note/Java

1. GC(Graphical Context) 클래스는 SWT의 그래픽엔진의 코어를 형성한다.

2. GC는 도형, 텍스트, 이미지를 그리는데 필요한 모든 메소드를 제공한다.

3. 컨트롤, 디바이스 또한 다른 이미지 위에 그릴수 있다.


일반적으로 그리기 라이프사이클은 다음과 같이 구성된다.

1. 그리려고 하는 대상의 GC를 생성하거나 얻음.

2. 그린다.

3. GC를 생성했다면, 소멸시킨다.


코드로 보면 다음과 같다.

GC gc = new GC(display);
gc.drawRectangle(...);
gc.drawText(...);
gc.drawImage(...);
gc.dispose();


일반적으로 paint handler에 그리기 코드를 넣는다.

final Canvas canvas = new Canvas(shell, SWT.NONE);
canvas.addPaintListener(new PaintListener() {
	public void paintControl(PaintEvent e) {
		GC gc = new GC(canvas);
		gc.drawFocus(...);
		gc.drawText(...);
		gc.dispose();
	}
});



GC 생성 피하기

GC를 새로 생성하면 dispose() 를 해야한다.

새로운 GC를 생성하지 않고 PaintEvent객체의 내장 gc를 사용하면 이를 회피할 수 있다.

코드는 아래와 같다.


final Canvas canvas = new Canvas(shell, SWT.NONE);
canvas.addPaintListener(new PaintListener() {
	public void paintControl(PaintEvent e) {
		e.gc.drawFocus(...);
		e.gc.drawText(...);
	}
});





이 댓글을 비밀 댓글로

[SWT] 이벤트

by Blogger 하얀쿠아
2012. 12. 7. 21:39 소프트웨어 Note/Java

이벤트

1. SWT는 2가지 유형의 리스너를 제공한다. : untyped / typed

2. untyped 리스너는 보다 간단한 코드를 작성할 수 있게 한다.

3. typed 리스너는 보다 더 모듈화 된 디자인을 할 수 있게 한다.


이벤트모델

1. SWT는 옵저버 패턴에 기반한 이벤트모델을 사용한다.

2. 다수의 리스너를 등록하여 알림메세지를 보낼 수 있다.

3. SWT에서는, 위젯과 Display만 이벤트 리스너를 가질 수 있다.



Typed 이벤트 리스너

타입이 정해진 이벤트 리스너(typed listner)는 단지 한종류의 특정한 이벤트 타입에 대해서만 listen 할 수 있다. 예를 들면, SelectionListener 는 SelectionEvent 라는 이벤트타입에 대한 리스너 이다.

untyped 이벤트 리스너는 이벤트를 듣기위한, 보다 generic 하며, low-level의 메카니즘을 제공한다.



Untyped Events와 Untyped 이벤트 리스너

타입이 정해지지 않은 이벤트 리스너(untyped event listener)는 아무런 타입의 이벤트를 듣도록 등록할 수 있다. SWT는 untyped 이벤트를 위해서 두가지 종류의 클래스를 가지고 있다.


1. Listener 라는 이름의 인터페이스

2. Event 라는 이름의 이벤트 클래스




이 댓글을 비밀 댓글로

Java에서 AES 128 암호화/복호화 구현

by Blogger 하얀쿠아
2012. 11. 16. 03:08 소프트웨어 Note/Java

AES 암호화


AES 소개

 1997년 1월에, 기존의 데이터 암호 표준, 즉 DES를 대체할 보다 강력한 알고리즘을 찾기 위한 공모 작업이 미국 상무부의 한 기관인 표준기술연구소(NIST)에 의해 시작되었다. 

 새로운 알고리즘이 충족해야 할 규격 요건으로는, 최소 128 비트나 192 비트 또는 256 비트 크기의 키를 지원하는 128 비트 크기의 블록 암호화를 사용한 대칭형 (암호화나 복호화를 하는데 동일한 키가 사용되는) 알고리즘으로서, 전 세계적으로 로열티 없이 사용할 수 있어야 하며, 향후 20년~30년 동안 데이터를 보호하기 위해 충분한 정도의 보안성을 제공할 것이 요구되었다. 

 또한, 이 알고리즘은 스마트카드 등과 같은 제한된 환경을 포함하여 하드웨어나 소프트웨어로 구현하기 쉬워야 했으며, 다양한 공격 기술에 대해서도 잘 방어할 수 있어야 했다.


 전반적인 선정 과정은 대중적 조사와 평가에 완전히 공개되었으며, 이러한 투명성으로 인해 제출된 모든 설계안들에 대해 최적의 분석이 가능하였다. 1998년에 NIST는 미국 안보국을 포함, 세계의 암호화 단체에 의해 기본적인 분석을 받게 될 15개의 AES 후보작을 선정하였다. 여기에 기반을 두고 1999년 8월, NIST는 보다 심도 있는 2차 분석을 받게 될 다음의 5개 알고리즘을 선정하였다.



MARS: IBM 연구소 제출 

RC6: RSA Security 제출 

Rijndael: 두 명의 벨기에 암호학자 Joan Daemen와 Vincent Rijmen 공동 제출 

Serpent: Ross Andersen, Eli Biham 그리고 Lars Knudsen의 공동 제출 

Twofish: Counterpane의 존경받는 암호학자 Bruce Schneier를 비롯한 대규모 연구팀 제출 



 위의 다섯 개 알고리즘은 모두 ANSI C와 자바 언어를 이용, 하드웨어와 소프트웨어 중심의 시스템 모두에서, 암호화와 복호화 속도 측정, 키와 알고리즘 설정 시간, 다양한 공격에 대한 저항성 등과 같은 심도 있는 시험을 거쳤다. 

 그 후, 이들 알고리즘은 새로운 암호화 체계를 깨보고자 자원하는 일부 팀을 포함 세계적인 암호화 단체들에 의해 다시 한번, 자세한 분석이 이루어졌다. 

 그 결과, 2000년 10월 2일에 NIST는 Rijndael를 표준안으로 최종 선정하였다.

 2001년 12월 6일, 미 상무부 장관은 민감하지만 비밀로 분류되지 않은 모든 문서들에 AES로서 Rijndael을 사용할 것을 규정하는 연방 정보처리 표준, 즉 FIPS 197을 공식 승인하였다.










AES 사용하기


자바에서 AES 알고리즘을 적용하여 중요한 데이터를 암호화하고 복호화하는 

것은 아주 쉬운 일이다.


import javax.crypto.Cipher;


import javax.crypto.KeyGenerator;


import javax.crypto.SecretKey;


import javax.crypto.spec.SecretKeySpec;


import org.apache.commons.codec.binary.Hex;


import org.junit.Test;


 


public class AESTest {


 


  private static String sKeyString = "" ;


  private static String message= "This is just an example";


 


  @Test


  public void testAESEncode() throws Exception {


 


    // 1. 128 비트 비밀키 생성


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


    kgen.init(128);


    SecretKey skey = kgen.generateKey();


 


    // 2. 비밀 키를 이렇게 저장하여 사용하면 암호화/복호화가 편해진다.


    sKeyString = Hex.encodeHexString(skey.getEncoded());


 


    // 3. 암호화 수행


    SecretKeySpec skeySpec = new SecretKeySpec(skey.getEncoded(), "AES");


    Cipher cipher = Cipher.getInstance("AES");


    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);


    byte[] encrypted = cipher.doFinal(message.getBytes());


 


    System.out.println("encrypted string: " + Hex.encodeHexString(encrypted));


 


    // 4. 복호화 수행


    cipher.init(Cipher.DECRYPT_MODE, skeySpec);


    byte[] original = cipher.doFinal(encrypted);


    String originalString = new String(original);


    System.out.println("Original string: " + originalString + " " + Hex.encodeHexString(original));


 


  }


}



예제와 같이 비밀키를 문자로 변환하여 저장해놓고 사용하면된다.


참조 : http://samse.tistory.com/entry/java-AES-128


출처 :

http://andang72.blogspot.kr/2012/02/aes.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+blogspot/VHwJi+(%EC%95%88%EB%8B%B9+%EB%B8%94%EB%A1%9C%EA%B7%B8)


같이보기 : AES 알고리즘 애니메이션


이 댓글을 비밀 댓글로

[Java] 비트 연산자 / 시프트 연산자

by Blogger 하얀쿠아
2012. 2. 2. 10:45 소프트웨어 Note/Java

[Java] 비트 연산자 / 시프트 연산자


자바언어에는 C/C++ 와 동일하게 비트연산자들인 '&', '|', '^', '~' 와 시프트연산자인 '<<' 와 '>>' 가 있습니다.

그러나 자바에만 있는 연산자가 있는데요.

바로  '>>>' 라는 연산자가 추가적으로 존재합니다.

순서대로 정리해 보도록 하겠습니다.


비트연산자

컴퓨터 내부의 데이터를 비트 단위로 비교하거나 조작할 때 사용한다.


1. 논리곱 (and) &

각 비트를 비교하여 양쪽 모두 1이면 1, 아니면 0을 반환함.


ex) a = 110, b= 220

a = 0 1 1 0 1 1 1 0

b = 1 1 0 1 1 1 0 0 

a&b =  0 1 0 0 1 1 0 0


2. 논리합 (or) |

각 비트를 비교하여 어느 한쪽이 1 이면 1, 그렇지 않으면 0을 반환함.


ex) a = 110, b= 220

a = 0 1 1 0 1 1 1 0

b = 1 1 0 1 1 1 0 0 

a|b =  1 1 1 1 1 1 1 0


3. 배타적 논리합(xor) ^

각 비트를 비교하여 한쪽이 1이고 다른 한쪽이 0이면 1을, 아니면 0을 반환함.


ex) a = 110, b= 220

a = 0 1 1 0 1 1 1 0

b = 1 1 0 1 1 1 0 0 

a^b =  1 0 1 1 0 0 1 0 


4. 1의 보수 표현(not) ~

각 비트를 반전시킨 값을 반환함.


ex) a = 110

a = 0 1 1 0 1 1 1 0

~a =  1 0 0 1 0 0 0 1



시프트 연산자

비트 열을 좌우로 지시한 만큼 이동시키는(shift) 연산자를 말합니다.
본문 처음에 말했듯이, C/C++ 에는 >> 와 << 만  존재하지만, 자바에는 추가적으로 '>>>' 연산자가 있습니다.

1. 왼쪽 시프트 연산자 <<

ex) 150 << 2
150 의 이진값을 왼쪽으로 2칸 시프트 합니다.
 
     1 0 0 1 0 1 1 0 : 150
1 0 0 1 0 1 1 0 0 0 : 600

위와 같은 결과. 왼쪽으로  두칸 밀면서, 비게 되는 오른쪽 두칸은 0으로 채웁니다.
만약 데이터를 담는 자료형이 byte 타입이었다면, (8bit) 왼쪽으로 밀린 2개의 비트는 삭제됩니다.

그런 경우 다음과 같은 결과가 됩니다
    0 1 0 1 1 0 0 0 :  88
 

2. 오른쪽 시프트 연산자 >> 

ex) 150 >> 2
150의 이진값을 오른쪽으로 2칸 시프트 합니다.

    1 0 0 1 0 1 1 0
    1 1 1 0 0 1 0 1 1 0

오른쪽으로 2비트 이동 한 후, 비게되는 왼쪽의 2개비트는 1로 채워지고, 오른쪽에서 2비트 넘어간 부분은 삭제됩니다. 
따라서 결과는 아래가 됩니다.
    1 1 1 0 0 1 0 1 

주의점 : 무조건 왼쪽에 비는 부분이 1로 채워지는 것이 아닙니다. -> 밀기전 최초 첫째짜리 값(MSB)과 동일한 값으로 채워집니다.


3. 논리 오른쪽 시프트 연산자 >>>

150 >>> 2
오른쪽으로 2비트 시프트 합니다.

자바에 추가된 논리 시프트는 오른족으로 밀면서 비게되는 앞쪽 비트를 무조건 0으로 채워넣는 것이다.

    1 0 0 1 0 1 1 0
    0 0 1 0 0 1 0 1 1 0

으로 되는 것. 비게 되는 왼쪽 2비트가 무조건 0 으로 채워집니다.
밀려난 오른쪽 2개비트 1 0 은 삭제됩니다.


G.711 코덱 구현을 하면서 비트연산자와 시프트 연산자를 사용할 일이 꽤 많았어요.
그런데 몇 몇 연산자의 용법을 자주 혼동하게 되어서, 다시 한번 정리를 해봅니다.


즐거운 코딩 하세요!



이 댓글을 비밀 댓글로
    • 알롱싸
    • 2012.08.07 17:28
    왼쪽 시프트 연산자 결과값 (1 1 1 0 0 1 0 1) 은 어떻게 나오는거에요?
    • 왼쪽 시프트 연산자가 아니라 오른쪽 시프트 연산자 에서의 예제를 말씀하신 것 같이 보이는 군요.

      10010110 에서 오른쪽으로 2칸을 밀게 되면 MSB(제일 왼쪽에 있는 숫자)인 1과 같은 숫자로 2개가 채워지고 밀린 숫자는 없어집니다.
      ->> 이렇게 2칸 밀면
      즉, [11]100101(10) 이렇게 되겠죠
      [ ] 안이 채워진 숫자이고, ( ) 안이 없어진 숫자 입니다.

[Java/Tip] 자바에서 unsigned byte 다루기.

by Blogger 하얀쿠아
2012. 2. 2. 10:12 소프트웨어 Note/Java
자바의 Primitive Data Type 들 중에는 unsigned 데이터 타입이 존재하지 않습니다.

unsigned를 특별히 사용할 일이 없을때는 의식하지 못하고 있었는데, 자바에서(정확히는 안드로이드에서 사용할 목적으로) 음성을 G.711 인코딩/디코딩 하기 위한 코덱을 구현 하던 중 깨닫게 되었습니다.

byte 타입을 unsigned 로 0~255 을 사용하고 싶었지만, 자바에서는 unsigned 키워드 자체가 존재하지 않아 byte 타입은 -128~127 의 값을 갖게 되어 있더군요. 즉 2's complement 의 값입니다.

하지만 제가 필요한 것은 0~255 의 범위값이었습니다. 
정확히는, C#에서 byte 타입으로 보낸 0~255의 값 (이진 값으로는 0000 0000 ~ 1111 1111 이 되겠죠) 을 자바에서도 0~255로 해석하도록 해야 했습니다.

그래서 이를 해결하기 위해 꼼수를 생각해 본 결과..

다음과 같이 하여 해결 할 수 있었습니다. 

byte value = xxx;
int nValue = 0;

if (value < 0)
 nValue = (int)value + 256;
else
 nValue = (int)value;

결과적으로 nValue에는 byte 값을 unsigned 로 변환한 값이 들어가게 됩니다.
원리는 간단하죠. 
0~127 값은 그대로 사용하면 됩니다. 2진수로 표현할 경우 0XXX XXXX 가 되기 때문이죠.
문제가 되는 -128~-1  은 2진수로 표현할 경우 1XXX XXXX 가 되며, MSB(most significant bit) 가 1이어서 어떻게 해석하느냐에 따라 표현되는 값이 달라지게 됩니다.  즉 unsigned 면 이를 128~255 로 표현 하겠죠. signed 면 2's complement 부호비트로 해석하여 -128 ~ -1 로 해석하는 것이죠.

결론은 -128 ~ -1 에 256을 더해주면, 됩니다.


 
이 댓글을 비밀 댓글로
    • 진짜궁금해서물어봄
    • 2019.02.21 21:08
    그냥 처음부터 byte에 128을 더하면 되지않나요??
      • ^^
      • 2019.02.27 15:06
      그러면 0~127을 표현할 수가 없지요~

      if를 사용하지 않고 싶다면
      int nValue = (int)value & 0xff 를 하시면 됩니다.

      1000 0000 인 byte 값을 int로 변환하면
      1111 1111 1111 1111 1111 1111 1000 0000 이 되고, 여기에
      0000 0000 0000 0000 0000 0000 1111 1111 을 and 연산해주면
      0000 0000 0000 0000 0000 0000 1000 0000 이 되어 -128이 아닌 128이 됩니다.

      자바의 거지같은 점이죠..ㅠㅠ
    • 박형준
    • 2019.06.11 12:10
    다른환경에서 암호화된 문자열 복호화 하는 과정에서 이 문제가 의심되서 검색해봤는데, 이런꿀팁이 있었다니 ㅜㅜ
    잘보고 갑니다

[Java] 정규표현식 표현 방법

by Blogger 하얀쿠아
2011. 12. 19. 19:45 소프트웨어 Note/Java

java.util.regex 패키지에 있는 Match 클래스와 Pattern 클래스를 사용하여 문자열을 정규표현식으로 검증할 수 있다.

boolean bln = Pattern.matches("^[a-zA-Z0-9]*$", this.input);


정규표현식은 다음과 같은 문법으로 되어 있다.

 ^ : 문자열의 시작을 나타냄.

$ : 문자열의 종료를 나타냄. \

. : 임의의 한 문자를 나타냄. (문자의 종류는 가리지 않는다)

| : or를 나타냄.

? : 앞 문자가 없거나 하나있음을 나타냄.

+ : 앞 문자가 하나 이상임을 나타냄.

* : 앞 문자가 없을 수도 무한정 많을 수도 있음을 나타냄. 
 만약, .* 으로 정규식이 시작한다면 시작하는 문자열과 같은 문자열이 뒤에 없거나 많을 수도 있는 경우에만 일치를 시킨다. 즉, abc 일 경우 시작문자인 a를 기준으로 a가 없을경우와 a가 무한정 많은 경우에도 true를 반환하기 때문에 abc의 경우는 true를 반환한다.

[] : 문자 클래스를 지정할 때 사용한다. 문자의 집합이나 범위를 나타내면 두 문자 사이는 '-' 기호로 범위를 나타낸다. []내에서 ^ 가 선행하여 나타나면 not 를 나타낸다.

{} : 선행문자가 나타나는 횟수 또는 범위를 나타낸다.
a{3} 인 경우 a가 3번 반복된 경우를 말하며, a{3,}이면 a가 3번 이상 반복인 경우를 말한다. 또한 a{3,5}인 경우 a가 3번 이상 5번 이하 반복된 경우를 나타낸다.

\w : 알파벳이나 숫자
\W : 알파벳이나 숫자를 제외한 문자
\d : 숫자 [0-9]와 동일
\D : 숫자를 제외한 모든 문자

위의 내용을 활용하여 다음 몇가지 예제를 만들어 볼 수 있다.

- 기본적인 문자열 검증 정규식
^[0-9]*$  :  숫자만
^[a-zA-Z]*$  :  영문자만
^[가-힣]*$  :  한글만
^[a-zA-Z0-9]*$  :  영어/숫자만

- 정규식 표현 예제

이메일 : ^[a-zA-Z0-9]+@[a-zA-Z0-9]+$  or  ^[_0-9a-zA-Z-]+@[0-9a-zA-Z-]+(.[_0-9a-zA-Z-]+)*$

휴대폰 :  ^01(?:0|1|[6-9]) - (?:\d{3}|\d{4}) - \d{4}$

일반전화 : ^\d{2,3} - \d{3,4} - \d{4}$

주민등록번호 : \d{6} \- [1-4]\d{6}

IP 주소 : ([0-9]{1,3}) \. ([0-9]{1,3}) \. ([0-9]{1,3}) \. ([0-9]{1,3})

이 댓글을 비밀 댓글로

Java Decomplier JAD 와 JadClipse 설치 및 활용

by Blogger 하얀쿠아
2011. 11. 6. 00:39 소프트웨어 Note/Java

Java Decomplier JAD 와 JadClipse 설치 및 활용

Jad는 바이트코드인 Java class파일을 디컴파일해주는 프로그램이다. JadClipse는 자바디컴파일을 이클립스에서 편리하게 사용할 수 있도록 해주는 이클립스 플러그인이다.

아래 순서대로 따라하면 쉽게 활용해볼 수 있다.

1. Jad및 JadClipse 다운로드

  * Jad : http://www.kpdus.com/jad.html
     윈도우 사용자는 Jad 1.5.8g for Windows 9x/NT/2000 on Intel platform 를 다운로드

  * JadClipse : http://sourceforge.net/projects/jadclipse
    자신의 이클립스 버전에 맞는 jadclipse3.x 를 다운로드



2. Jad와 Jadclipse를 적절한 위치로 복사하기

   jad의 압축을 풀어 jad.exe 를 C:\Jad 폴더를 만들어 복사한다.
   jadclipse는 net.sf.jadclipse_3.x.0 폴더를 eclipse의 plugins 폴더로 복사한다.



3. jadclipse 사용을 위한 이클립스 환경설정

Window - Preferences - Java - JadClipse에서
 - Path to decompiler > c:\jad\jad.exe  
 - [v] Reuse code buffer 체크




한글이 깨지는 것을 방지하기 위해, JadClipse - Misc 에서 - [v] Convert Unicode strings into ANSI strings 를 체크한다.




디컴파일을 위한 모든 준비가 끝났다.


4. 디컴파일 사용하기

디컴파일하고자 하는 class파일을 더블클릭하면, 소스가 보여지게 된다.






이 댓글을 비밀 댓글로

부분문자열을 얻는 방법 - Java와 SQL

by Blogger 하얀쿠아
2010. 11. 6. 21:11 소프트웨어 Note/Java


JAVA의 String 메소드중 하나인 Substring 은 부분문자열을 얻을때 사용한다.

Substring(int beginIndex, int endIndex) 의 형태를 가진다.
beginIndex 부터 endIndex 까지를 부분문자열로 취하겠다는 뜻이다.
(endIndex의 문자는 제외가 된다!!)

예)
String str = "19000101-1234567"
str.substring(10, 17) 하면 1234567 을 부분문자열로 반환한다. (10부터 16까지 7자리를 읽어온다)

 

SQL에서는 부분문자열을 얻는 substr 라는게 있다.
형태는 substr(string S,int N1,int N2) 이다.
뭐냐하면 문자열 S를 N1 번째 문자부터 시작해서 N2 개 만큼 부분문자열로 취한다는 것이다.

예)
select substr("19000101-1234567", 10, 7) from dual
이렇게 하면 주어진 문자열 19000101-1234567 의 10번째부터 7개의 문자를 부분문자열로 취한다.
즉 1234567을 얻는다.


 

이 댓글을 비밀 댓글로