http://cafe.naver.com/jjdev/1364



내 경우에.. 파일 관리 시스템을 만들면서 팩토리 패턴을 사용할때 해당 파일작업(copy,delete,rename,move)을 수행할
워커(copyWorker,deleteWorker)를 이름과 실제 클래스 명(패키지네임 포함)을 xml파일을 통해 저장하고 로드해서 사용
했었다.

스프링 프로젝트에서도 요런식으로 쓰나보나.. 내가 모르는건 root의 개념.. 및 패키지간 관계의 표현인듯..?


+ jsp 책을 보다가.. was (web app service)를 배포할때 파일들,리소스들의 접근 경로에 대한 문제도 생각해야한다.


by givingsheart 2014. 1. 2. 08:53
********************************************************
내가 약 20분 삽질한 constraint 두개 이상쓰기..

create table employee(
employee_no number(3),
salary varchar2(50),
...
department_no number(3),

constraint employee_pk primary key (employee_no),  //칼럼은 괄호()로 .. 추가로 제약조건 주고 싶으면.. 콤마 ,로  []아님
constraint department_fk foreign key (department_no) references department (department_no) <-- 여기에 delete cascade
)


create table employee(
employee_no number(3),
name varchar2(50) not null,
position varchar2(50) not null,
salary number not null,
department_no number(3) null,  <-- 신입사원이라면 소속부서가 아직 결정 안되었을수 있음으로!
constraint employee_pk primary key (employee_no),
constraint department_fk foreign key (department_no)
references department (department_no) on delete cascade  <--요 정의는 자식 테이블이 참조하고 있기 때문에 부모테이
블을 삭제(drop)할수 없다는 정의! data define language  + 구분할 개념.. 부모테이블 전체가 아닌, 테이블의 행(레코드)를
삭제할 경우 자식테이블의 참조 값도 없어짐.

내 예측엔 on delete cascade로 ddl 했을때 참조되는 부모 테이블을 변경시 , 자식테이블의 컬럼(fk)만 비워질 것이라 
생각했는데.. 결과는 삭제한 fk를 갖고 있던 자식 테이블의 모든 레코드가 삭제 되었다!  아래는 테스트 코드

CREATE TABLE DEPARTMENT(
DEPARTMENT_NO NUMBER(3,0),
DEPARTMENT_NAME VARCHAR2(50) NOT NULL,
LOCATION VARCHAR2(50),
CONSTRAINT DEPARTMENT_PK PRIMARY KEY (DEPARTMENT_NO)
);

INSERT INTO department VALUES(1,'영업부','강남구 논현동')
INSERT INTO department VALUES(2,'인사부','강남구 역삼동')
INSERT INTO department VALUES(3,'법무부','강남구 삼성동')
INSERT INTO department VALUES(4,'전략기획및 개발','강남구 삼성동')



create table employee(
employee_no number(3),
name varchar2(50) not null,
position varchar2(50) not null,
salary number not null,
department_no number(3) null,
constraint employee_pk primary key (employee_no),
constraint department_fk foreign key (department_no)
references department (department_no) on delete cascade
)

INSERT INTO employee 
VALUES(1,'장호','부장','5000000000',4)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(2,'홍길동','사원','500',4)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(3,'강길동','사원','500',4)

DELETE FROM department WHERE department_no = 4

SELECT * FROM employee


아래의 경우 drop table department; 했을 경우 실패했으나 ,, drop table department cascade constraint; 로 지워줄수있음.
물론 테이블의 삭제가 일반적인 일은 아님.(데이터가 다 날아감으로)


흠.. 직원 a씨는 인사부서 였는데.. 인사부(human resource)가 사라졌다면.. 직원 a씨의 전체 정보를 삭제할까? 
아니면 컬럼만 삭제할까?


구분할 개념
테이블 생성시.. 제한 조건(constraint)로 foregn key references 부모 테이블 (칼럼이름) on delete cascade 의 경우
참조 무결성을 위해 부모 테이블의 드랍에 제한을 거는 것이고..

drop table 부모테이블 cascade constraint 의 경우는.. 자식 객체의 fk 칼럼의 레퍼런스(참조)속성을 날려버린다는
의미 같음. (해당 칼럼을 삭제하진 않을듯함?)

)

*************************************************************




http://blog.naver.com/kookh1?Redirect=Log&logNo=120192625407



ALTER TABLE MEMBERINFO MODIFY(ID NUMBER(6,0) NOT NULL);  <-- 요놈도 괄호 삽질 ㅠㅠ

alter table에 대해서..


key의 타입(super,candiate,primaty,alter...) 과 무결성에 대해

****************************************************
 pk는 not null 과 unique 를 포함하는 개념!

흑.. 완전 짜증..

create table memberinfo(
id number(6,0), //pk 인덱스니까 검색빠르게 문자열보단.. 숫자로 줬는데 흑;;
pw varchar2(10) not null,
name varchar2(20),
constraint memberinfo_pk primary key (id)   <--- id를 ()로 안감싸서 한참 삽질 ㅠㅠ  <--요이유가. 한번에 여러 필드에
                                                                    제약조건(constraint primary key 를 적용할수 있기에.. ()로 식별이 
                                                                    필요한듯.. constraint memberinfo_pk primary key(id, pw, name) 요렇게..
                                                                    물론 실전이라면.. id = pk , nickName = pk, 주민번호 = pk 요런식 이겟지만..
) ;  <-- ;는 해도 되고 안해도 되고..



er 모델링, 클래스 모델링, 또.. 모델 드라이븐 디자인...









//2013-12-19  쿼리 가지고 놀기


SELECT * FROM MEMBERINFO;

SELECT NAME PW FROM MEMBERINFO;
SELECT NAME FROM MEMBERINFO WHERE ID = 'id3';
UPDATE MEMBERINFO SET NAME ='나길동' WHERE ID = 'id2';

UPDATE MEMBERINFO SET ID =5 WHERE NAME = '마길동';

INSERT INTO memberinfo VALUES(4,'하길동','비번66')

INSERT INTO MEMBERINFO(ID,NAME) VALUES('id5','5');
INSERT INTO MEMBERINFO values('id4','라길동','4');
DELETE FROM MEMBERINFO WHERE ID = 'id4';

ALTER TABLE MEMBERINFO DROP COLUMN ID;
ALTER TABLE MEMBERINFO DROP CONSTRAINT ID_PK;

ALTER TABLE MEMBERINFO ADD(ADDRESS VARCHAR2(50));
ALTER TABLE MEMBERINFO MODIFY (ADDRESS VARCHAR2(100));
ALTER TABLE MEMBERINFO ADD CONSTRAINT ID NUMBER PRIMARYKEY;

ALTER TABLE MEMBERINFO ADD PRIMARY KEY(ID NUMBER(6,2));

ALTER TABLE MEMBERINFO MODIFY (ID NUMBER(6,0)[PRIMARY KEY]);

ALTER TABLE MEMBERINFO ADD(ID2 NUMBER CONSTRAINT PRIMARY KEY);

ALTER TABLE MEMBERINFO MODIFY (ID NUMBER);

DROP TABLE MEMBERINFO2;
CREATE TABLE MEMBERINFO2(ID NUMBER(6,0) PRIMARY KEY, PW VARCHAR2(20), NAME VARCHAR2(20));

ALTER TABLE MEMBERINFO2 MODIFY(ID NUMBER(6,0) NOT NULL);

DROP TABLE DEPARTMENT;

CREATE TABLE DEPARTMENT(DEPARTMENT_NO NUMBER(3,0) PRIMARY KEY, DEPERTMENT_NAME VARCHAR2(50) NOT NULL,
LOCATION VARCHAR2(50));


DELETE FROM department WHERE department_no = 4  



drop table employee

CREATE TABLE DEPARTMENT(
DEPARTMENT_NO NUMBER(3,0),
DEPARTMENT_NAME VARCHAR2(50) NOT NULL,
LOCATION VARCHAR2(50),
CONSTRAINT DEPARTMENT_PK PRIMARY KEY (DEPARTMENT_NO)
);

INSERT INTO department VALUES(1,'영업부','강남구 논현동')
INSERT INTO department VALUES(2,'인사부','강남구 역삼동')
INSERT INTO department VALUES(3,'법무부','강남구 삼성동')
INSERT INTO department VALUES(4,'전략기획및 개발','강남구 삼성동')

UPDATE department SET location = '제주도 성남시'
UPDATE department SET department_name = '전략기획' WHERE department_no = 4
UPDATE department SET location = '논현동' WHERE department_no = 1;
UPDATE department SET location = '역삼동' WHERE department_no = 2;
UPDATE department SET location = '삼성동' WHERE department_no = 3;
UPDATE department SET location = '동동' WHERE department_no = 4;

INSERT INTO department(department_no,department_name,location) VALUES(5,'')

SELECT * FROM department
SELECT * FROM department ORDER BY department_no ASC

create table employee(
employee_no number(3),
name varchar2(50) not null,
position varchar2(50) not null,
salary number not null,
department_no number(3) null,
constraint employee_pk primary key (employee_no),
constraint department_fk foreign key (department_no)
references department (department_no) on delete cascade
)

INSERT INTO employee 
VALUES(1,'장호','부장','5000000000',4)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(2,'홍길동','사원','500',4)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(3,'강길동','사원','30000',4)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(4,'나길동','ㄹㅇㄹㅇ','3004400',3)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(5,'다길동','ㄷㄷ','3003300',2)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(6,'라길동','ㅂㅂ','6630000',1)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(7,'길동','ㅂㅂ','66320000',3)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(8,'길동이','ㅂㅂ','66000',3)


DELETE FROM department WHERE department_no = 4

SELECT * FROM employee WHERE department_no IN(1,3) ORDER BY name ASC
SELECT * FROM employee WHERE department_no NOT IN(1,3) ORDER BY name ASC

SELECT * FROM employee WHERE department_no IN(1,3) ORDER BY department_no ASC

SELECT * FROM employee WHERE name LIKE('%동')
SELECT * FROM employee WHERE name LIKE('%동%')
SELECT * FROM employee WHERE name LIKE('길%')
SELECT * FROM employee WHERE name LIKE('__동')
SELECT * FROM employee WHERE name LIKE('__') ORDER BY salary DESC
SELECT * FROM employee WHERE name LIKE('%') ORDER BY salary DESC
SELECT * FROM employee WHERE name LIKE('_동') 

SELECT * FROM employee WHERE name NOT LIKE('_동')


글고 조인 연산시.. 테이블의 별칭을 줄수 있다. 왜냐면 네임스페이스 처럼
이름 식별을 위해서~ 글고 뒤에 오더정렬을 안해주면 입력 순서가 유지가 안된다.
그럼으로 이를 통해 dbms가 데이터를 저장하는 방식이 map<pk,Object data~~> 임을 
유추할수 있다. 검색 속도 증가를 위한 인덱싱이란 무얼까? 
SELECT * FROM employee e, department d <--불필요한 정보까지 싸그리 가져온 경우
WHERE e.salary > '300600' AND d.department_name = '법무부' AND e.name LIKE('_길_')
ORDER BY e.name ASC
아참.. where 조건절을 ()로 묶어줄 수 있다.
SELECT e.name FROM employee e, department d 
WHERE e.salary > '30000' AND d.department_name = '법무부' AND e.name LIKE('_길_')
ORDER BY e.name ASC


SELECT * FROM employee

alter table employee modify(department_no number(3) foreign key);


(추가)난 여전히 학원 과정(아주 얕게 RDB 수업 & JDBC를 활용한 CRUD 테스트 실습)과는 별개로
공부및 추가 학습을 하고 있다. (오라클 DBMS 아키텍처및 각종 쿼리와 최적화, 테이블 설계, 정규화
비정규화등..) RDB도 제대로 이해를 못하고.. 빅데이터를 알게 되었다.(대용량 DB 아니다)


by givingsheart 2014. 1. 1. 16:45

1. io를 통한 채팅 프로그램 개발 경험이 정말로 큰 도움이 되었음.(종료) 

   =>덕분에.. 이젠 내가 대충 소켓,스레드 사용해서 어떤 프로그램을 만들고 싶다라고 생각이 들면.. 자바 도큐만
   보면서 구현이 가능할듯.. 뭐랄까.. 나름 상당한 고민을 했었고.. 그만큼 풀어냈다고 혼자 착각중임 -_-;
   큰 수확은.. 예외 핸들링을 통한.. while() 업무의 종료 조건 / 수행 조건의 구분이엇고.. 스레드에게 작업을
   시킨다는 것,병렬 처리의 필요성과 순차적 의존에 대한 한계등.. 대해서도 여러가지 깨달음이 있었음..  
    글고 PrintWriter(system.out) .. 그리고 오토 플러쉬.. 머리에 담아 뒀었는데.. 실제로 시행착오를 겪었고.. 
    디버깅해서 원인을 찾고.. 뒤통수 한대 맞은 기분이었음..OTL

2. 기존 nio 계획중 모든 기능 구현이 아닌, 우선 간단한 버전 (채널및 셀렉터 사용, 다이렉트 버퍼 사용)
   으로 다중 (63명) 채팅 룸 하나 구현. (한마디로 셀렉터 하나만 사용하겠다는 의미 클라1개,서버 2개) (오늘중으로 처리 가능)

3. 앞으로 db나갈 예정인데.. 쿼리에 대해 학습겸 해서..  간단하게 쿼리 생성 툴 만들 예정. (예전에 jsp
   교재 땜에 마구잡이로 구현은 해놨었음.)

  =>요걸 실전에 쓸수 있을정도로 만들라면.. ui는 대충 구현(swing사용)..  아주 복잡해질 reflect도 집어치우고..

   1.그냥 사용자가 클래스 이름(=테이블이름), 멤버 필드 타입,변수명 타입,변수명,(pk = 인스턴스 구분까지) ... 
     지정하게 하면 
   2.이클립스가 세터,게터 자동 지원하는 것처럼..  특정 필드 세터(update쿼리) , 게터(selecte쿼리)를 생성
     해줌 (=>xml 파일로 쏴주는 것도 간단할듯.. java.util.property 클래스 땡큐~
   3.복잡한 테이블간 or 행(row)간 or 열(col)간  where  xx and bb  join 등의 복잡한 연산은.. 접어둠


   vs  

   1. data define language : create , alter, drop  생성
   2. modify : insert, update, delete 생성
   3. query : select 
   로 구분하고.. 각 타입에 따라 패턴이 있을테니.. 고민해보고 만들어 봐도.. 

  vs row(레코드) 단위로 처리: delete 
      column(필드) 단위로 처리: insert , update, selete

결론: 관계형 db 만세~  테이블 = 클래스 , pk column & 하나의 row = 인스턴스 , 각각의 column = 클래스 멤버필드
   음.. 그리고 잘은 모르지만.. get,set,조회,정렬,삽입,삭제,생성,소멸등.. 복잡한 비지니스라는 것도 잘개 쪼개면.. 
   거의다 쿼리 단위로 쪼개질듯..  글고 클래스간 관계(association)도 fk를 통해서 표힌이 가능하고..하여간 db쿼리 공부겸 
   툴 만들기 늦어도 다음주 부터 시작. 

추가: 관계형 db의 한계.. 객체 지향의 interface , extends 등의 상속과, 해당 클래스와 메서드간 연결을 못한다. 
       그럼으로 POJO(Plain old java Object) 처럼 아무것도 상속 받지 않고, 겟,셋만 구현한 빈 클래스로 dao를
       만들어서.. 사용한다. 서버와 디비 사이단에.. 하이버네이트, 또 머가 있었드라..?

자바 ee5 : 애플릿 컨테이너 , 어플리케이션 컨테이너, 웹 컨테이너(jsp컨테이너로 jsp,서블릿 관리), ejb컨테이너,
      데이터베이스

--front end--
JAVA CLIENT LAYER (html,xml,css,기타등등.. view단에서 바로 db와 연결할라면.. JQuery=Ajax + html)
{
client tier :일반 어플리케이션 client , 다이나믹 웹 어플리케이션 client
}

--back end--  (jsp 등등)
JAVA SEVER LAYER (사용자=클라이언트의 요청(view)에 따라 컨트롤하여 비지니스 수행(control -> model = db쿼리작업)
{
web tier : jsp 페이지
business tier : EnterprizeBean A , EnterprizeBean B , ...
}

DATABASE LAYER
{
els tier : DB A , DB B ...
}

(etc)오늘 받은 jdbc 쿼리 문서중.. where 조건 연산자를 보니까.. 프로그래밍 언어의 조건(논리,비교) 연산자와는 조금 달리
    실제 비지니스에서 필요한 조건 연산(범위,테이블간(도메인)간 조인, 인스턴스(로우)간 컬럼간.. 등등)과 데이터 베이스의 
     무결성(not null)등등.. 그리고 제공하는 내장 프로시저의 경우.. api를 공부하듯 보면 될듯..
     아 글고 join 문(& 연산자 같음) 사용시 퍼포먼스 올리기 위해 "인덱스"를 사용하는 것이 좋습니다. 란 말이 있는데.. 예전에
     담배 피다 떠올린.. 숫자 중복 코드에서 배열의 인덱스 + 논리 연산자만 가지고 했을때 약 20배의 성능이 좋아 졌던 것과 
     유사한듯.. 
     그게 아니라도 최소한 문자열 비교보단, 숫자 비교가 빠르지..
     
     select = 컬럼(필드),컬럼,컬럼...
     from = 테이블,테이블,테이블...  
     where = 조건 & 조건 or 조건... 
     values = 값, 값, 값...
     
    말 그대로 if else 의 조합 + 게터,세터 아닌가..

    특정 부서의(테이블) 특정 이름 직원(컬럼일수도 있고 테이블일 수도 있고)의 연봉정보(테이블)를 알고 싶어요~  
    조인을 연산을 통해.. 추출하거나, 서브쿼리를 이용한다고 함. 

    채팅 프로그램에 db를 사용한다면;; p2p가 아니고 서버 브로드 캐스트 방식일때.. 해당 채팅룸의 모든 데이터를 db에
    남겼다면,..  xxx날짜에 채팅한 사람중 로그인,아웃 시간이(사용시간) 3시간이 넘고 여자면서 나이가 20~30대인 사람들
    의 데이터를 조회해주세요. 란.. 요청에 대해 어떻게 처리를 할것인가?  전부 and , between 조건으로 처리할 것인가?
    테이블을 멋지게 설계해두고 효율적인 방법으로 타겟을 좁혀 나갈것인가..


    오.. oracle sequence 란게.. 순차적으로 자동증가 하는 값을 생성하는 오라클 객체라네..  내가 오늘 채팅 구현할때
    쬐끔 신경쓰였던 것이.. 클라가 accpet 단에서 개별적으로 i/o스레드를 배정받는데.. 이 경우에 채팅에서 유저를 식별
    하기 위한 name or nickname or id를 어떻게 처리해야 할까였다. 왜냐하면 유저에 대한 아웃풋 스트림의 경우 다중 채팅
    임으로 모아둘(컨테이너를 포함하는 클래스) 필요가 있었고.. 식별을 일반 리스트처럼 인덱스의 경우는 별 문제가 없지만..
    , 셋or 맵 구조라면.. 중복되지 않는 키값이 필요했다. 내 경우엔 i/o 스레드 객체에 소켓 정보를 저장해두지 않고 인풋 스트
    림만 개별 스레드가 보관하는 방식이라.. 아웃풋 스트림을 모아둔 클래스에 서비스 메서드로 중복되지 않는 문자열을 만들게
    끔.. 초간단하게.. guest 란 기본 문자열에 number란 static 변수를 0부터  getUniqueName() 호출 시마다 return "guest" +
     num++; 요 딴식으로 구현했었다. -_-; (자동 증가 = 시퀀스라니까.. 떠올랐다;;)
     key&Object로 하냐..(물론 일반 프로그램이라면.. 클라쪽에서 어셉 요청
    (한마디로 서버주소 적은 소켓 객체 생성 성공) 

(etc2) java.sql.Connection , java.sql.Statement, java.sql.ResultSet, PreparedStatement 등등.. 내가 공부하고 있는 jsp
 교재를 보면서 한번씩 보고 이해하고 사용해봤던 클래스들이다.. 디비와의 통신(i/o스트림) 또한 자바라면 .. 소켓io,파일
 io와 거의 똑같이 설계했을 것이다. 스트림 생성-> i/o작업 -> 스트림 종료..  익숙해서 반갑다 ^_^//

 Class.forName()도 나오네..(reflect 개념에 속함.. 문자열에 매치하는 타입이 있으면 리턴) 내가 이번에 파일 매니저 만들면
 서 구현했던 팩토리 클래스도 xml에서 읽어올때 
 workerMap.put((String)entry.getKey(), Class.forName((String)entry.getValue())) 요렇게 했었는데..

 아.. 뒤에 보니까 드라이버 이름,db url,포트, 계정 이름, 비번등.. .. 약 한달전인가.. 오라클 12c 갈때 sid가 먼지도 몰랐던 때..
 도대체 왜 계정 생성이 안되는지.. 10시간 넘게 고민했었던 당시의 기억이 떠오른다.. 내 경운 11g 로 버전 낮춰서 초 간단하게
 계정 생성 성공.. (12가 먼가 복잡한 개념이 있었음;;)

  dbConnection.createStatement()도 눈에 익숙하고.. 정말로 jsp 책에 절하고 싶은 기분.. 리절트셋이니.. 트랜잭션이니..
  등등.. 리절트 셋의 개념도 잡아 주었고..커넥션 풀링의 개념은.. 책에서도 나왔었고.. 이번에 nio 서버 구현 공부를 하면서
  풀링에 대한 고민도 했었고.. 

  하핫.. 짧은 교재 벌써 다 봤네.. 조금 쉬었다가 nio 채팅 서버,클라 구현 GoGo!
    
(etc3)똥을 싸놓은 파일 매니저의 경우에.. 그 뒤에 꽤나 큰 수정이 있었다.. 허나 중요한 것이 아니기에 우선순위에서 밀림
   .. 다음주는 db쿼리 툴 , jsp 에 우선 순위.. 내 웹서버(정확히는 jsp 컨테이너인 톰캣아..스클립틀릿과 html들아 지못미..)


by givingsheart 2014. 1. 1. 16:41

아하하..


표준 콘솔 출력도 내가 포장해서 쓰려다가.. 
내가 만들라던 PrintWriter 객체나, System.out 이란 객체나.. 똑같은 넘들인것을..

그러니 만들어 질리가 없고.. 작동 할리도 없지.. 생각이 짧았음.
(단순한 실수였는데 문제를 빠르게 풀지 못했었음)


by givingsheart 2014. 1. 1. 16:41

http://blog.naver.com/genesung?Redirect=Log&logNo=130082920571 님감사해요.. (__ ) 


사실 채팅 프로그램에 대단한 보안이 필요한건 아니고.. 

대충 보아하니.. des인데.. 그럼 서버측, 클라측 코드에 String Key 하나씩 심어놔야하나?

어디다가 숨겨놔야 안전할까...끙 -_-;;;  그나저나 text.getBytes()하고 있네.. 그나마 반갑다.

내가 암호,복호화할 데이터도.. directByteBuffer님까 -_-;



import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

 

private static final String _cipherAlgorithm = "DES";

 

String encryptText(String text, String key)
{
    String encrypted;
        
    try
    {
        SecretKeySpec ks = new SecretKeySpec(generateKey(key), _cipherAlgorithm);
        Cipher cipher = Cipher.getInstance(_cipherAlgorithm);
        cipher.init(Cipher.ENCRYPT_MODE, ks);
        byte[] encryptedBytes = cipher.doFinal(text.getBytes());
        encrypted = new String(Base64Coder.encode(encryptedBytes));
    }
    catch (Exception e)
    {
        e.printStackTrace();
        encrypted = text;
    }
        
    return encrypted;
}

 

String decryptText(String text, String key)
{
    String decrypted;

    try
    {
        SecretKeySpec ks = new SecretKeySpec(generateKey(key), _cipherAlgorithm);
        Cipher cipher = Cipher.getInstance(_cipherAlgorithm);
        cipher.init(Cipher.DECRYPT_MODE, ks);
        byte[] decryptedBytes = cipher.doFinal(Base64Coder.decode(text));
        decrypted = new String(decryptedBytes);
    }
    catch (Exception e)
    {
        decrypted = text;
    }

    return decrypted;
}

 

byte[] generateKey(String key)
{
    byte[] desKey = new byte[8];
    byte[] bkey = key.getBytes();
        
    if (bkey.length < desKey.length)
    {
        System.arraycopy(bkey, 0, desKey, 0, bkey.length);
            
        for (int i = bkey.length; i < desKey.length; i++)
            desKey[i] = 0;
    }
    else
        System.arraycopy(bkey, 0, desKey, 0, desKey.length);
        
    return desKey;
}


'프로그래밍 > 보안' 카테고리의 다른 글

jvm의 입장?  (0) 2014.01.02
"보안" 관련 문서(2013.12.11 자바 보안객체 사용 추가)  (0) 2014.01.01
by givingsheart 2014. 1. 1. 16:35

결론:thread safe가 필요할 경우 아래의 패키지를 활용할 것! 

 멀티스레드 동기화 문제에 대한 자바측의 편의 제공 클래스! java.util.concurrent 패키지!

=>한마디로 데이터를 원자적으로 보호한다. (내부적으로 synchrozied 처럼 lock, unlock 래핑한 것인듯.. 
   참조를 보호하는 거야.. reflect가 있으니.. Class 를 Object로 처리 가능할테고.. 아님 말고 -_-;)


패키지 java.util.concurrent.atomic

단일의 변수에 대한 락 프리로 thread 세이프인 프로그래밍을 지원하는 클래스의 소규모의 툴 킷입니다.


************************기타 찌끄레기 방법? 심플하니 좋은건가?********************


멀티쓰레드 환경에서 클래스의 멤버변수를 안전하게 사용하기 위해서 사용하는 방법이 sychronized 블록을 사용하거나, 변수를 volatile로 선언하는 방식이 있습니다. 두 방식의 차이에 대해 알아보았습니다.

 

Question of the month: Volatile vs. Synchronized re-visited

 

먼저 각각의 방식에 대한 한 쓰레드에서 처리 방식을 살펴보면 다음과 같습니다.

 

volatile

synchronized

Get a global lock on the variableGet a global lock on the monitor
Update the one variable from main memoryUpdate all shared variables that have been accessed from main memory
Process some statements
Write any change of the one variable back to main memoryWrite all shared variables that have been changed back to main memory
Release the lockRelease the lock

 

여기에서 알 수 있듯이 volatile이 선언되지 않은 멤버변수는 sychronized 블록이 아닌 곳에서 사용할 경우, 쓰레드가 변수값들을 복사해서 사용하기 때문에 다른 쓰레드에서 값을 변경했을 경우 같은 변수임에도 불구하고 실제와 다른 값을 읽을 수 있다는 것입니다.

 

Use Synchronized or Volatile when Accessing Shared Variables

 

각각의 방식의 장단점을 살펴보면 다음과 같습니다.

 

TechniqueAdvantagesDisadvantages

synchronized

Private working memory is reconciled with main memory when the lock is obtained and when the lock is released.Eliminates concurrency.

volatile

Allows concurrency.Private working memory is reconciled with main memory on each variable access.


by givingsheart 2014. 1. 1. 16:33
지식을 나눠주시니.. 감사할 따름.. ^^

http://helloworld.naver.com/helloworld/  

아래의 결론 = 대부분의 서비스에 UTF-8 이 일반적이다.

Java와 한글

Java는 String에서 사용하는 인코딩은 UTF-16 BE(Big Endian)이다. 문자열 전송/수신을 위해서 직렬화가 필요할 때에는 변형된 UTF-8(Modified UTF-8)을 사용한다. Java의 DataInput, DataOutput 인터페이스 구현체에서는 문자열을 기록하거나 읽어들일 때 이 변형된 UTF-8을 사용한다. 변형된 UTF-8의 인코딩 규칙은 표5에서 볼 수 있다.

표 5 변형된 UTF-8 인코딩 규칙

코드 범위

인코딩 규칙

U+0000

11000000 10000000 (0xC080)

U+0001 ~ U+FFFF

UTF-8 인코딩과 동일

U+010000 ~ U+1FFFFF

UTF-16 인코딩한 값을, UTF-8 인코딩함 (CESU-8)

변형된 UTF-8에서 U+0000을 2바이트로 표시하는 이유는 인코딩된 결과에 널 문자(00)가 나타나지 않도록 하기 위해서이다. C언어와 같이 NULL 문자를 문자열의 끝으로 처리하는 언어에서 U+0000을 읽을 때, 문자열의 끝으로 잘못 처리하는 일이 없도록 하기 위해서이다. 그리고 U+010000 이상의 코드를 표현하기 위한 CESU-8(Compatibility Encoding Scheme for UTF-16:8-bit)은 UTF-8의 변형인데 코드 포인트 U+010000 이상의 글자를 표현하기 위한 방법이다. Java에서 글자를 표현하기 위해서 2바이트 크기를 가지는 char를 사용하는데, 전체 유니코드 글자를 2바이트로 표현할 수 없기 때문에 이러한 방식을 사용한다. Java의 변형된 UTF-8은 CESU-8에 NULL 문자 처리(U+0000)을 추가한 것이다.

한글의 표현과 인코딩

Java에서는 유니코드의 코드 포인트 값을 String.codePointAt(int); 메서드를 이용하여 확인할 수 있다. 다음은 '한글'(U+D55C U+AE00)에 대한 코드 포인트 값을 출력한 예이다.

1
2
3
4
5
String string = "한글";
for (int i = 0; i < string.length(); i++) {

    System.out.print(String.format("U+%04X ", string.codePointAt(i)));
}
System.out.println();

코드 포인트에 대한 개념을 이해하고 있다면, 한글/영어 개수를 세거나, 바이트 수에 맞추어 한글/영어 문자열 자르기 등은 어렵지 않을 것이다.

Java에서 인코딩된 값을 알아보려면, getBytes() 메서드를 이용하여 확인할 수 있다. 다음은 '한글'에 대한 인코딩 값을 출력한 예이다.

1
2
3
4
5
6
String string = "한글";

byte[] bytes = string.getBytes();

for (byte b : bytes) {

    System.out.print(String.format("0x%02X ", b));
}
System.out.println();

여기에서 염두에 둘 점은 Java에서 문자열은 항상 UTF-16 BE 인코딩으로 저장되며, file.encoding시스템 프로퍼티에 의해 인코딩 값이 결정된다는 점이다. 특히 C언어를 많이 다루어 본 개발자라면 문자열을 C의 1바이트 char 배열로 여기는 경향이 강하기 때문에 이 차이점을 잘 이해해야 한다. 언어 차원에서 유니코드와 같은 캐릭터 인코딩을 지원하지 않는 C와 달리 Java에서는 언어 차원에서 유니코드와 여러 코드 페이지를 지원한다.

Java는 String 객체 내부(메모리 상에서) UTF-16 BE 인코딩으로 문자열을 저장하고, 문자열을 입/출력할 때에만 사용자가 지정한 인코딩 값 또는 운영체제의 기본 인코딩 값으로 문자열을 인코딩한다. JVM 기본 인코딩은 JVM 로딩 시에만 초기화되므로, 코드 중간에서 file.encoding 프로퍼티를 바꾸는 것은 아무 의미가 없다. 만약 file.encoding이 지정되어 있지 않다면, OS 환경 변수(예: LANG) 값을 따른다. Java에서 글자를 깨뜨리지 않으려면, 문자 집합의 이름을 지정해야 한다. 예를 들어, 문자열 객체의 getBytes() 메서드를 이용하여 바이트 배열을 얻고자 할 때, getBytes() 대신 getBytes(String charsetName) 메서드를 사용하고, 반대로 바이트 배열에서 문자열 객체를 얻고자 할 때, new String(byte[] b) 대신 new String(byte[] bs, String charsetName) 메서드를 사용한다.

웹과 한글

한글 처리, 특히 웹에서의 한글 처리는 무척 까다롭다. 그 이유는 사용자의 환경이 매우 다르다는 데 있다. 웹 프로그래밍을 하려면, 운영체제의 기본 인코딩, Java 소스 코드의 인코딩, JSP 파일의 인코딩, HTTP 요청의 인코딩, HTTP 응답의 인코딩, 데이터베이스의 인코딩, 파일의 인코딩 - 이렇게 많은 인코딩과 마주하게 된다.

 

a0a6fa0efd3c5c256f870861df6f7e46

웹에서 한글이 왜 깨지는가? 브라우저 인코딩 값과 서버 인코딩 값이 다르기 때문이다. Tomcat에서는 파라미터 인코딩 및 키와 값을 설정하기 위해 org.apache.catalina.connector.Request.parseParameters 메서드와 org.apache.tomcat.util.http.Parameters.processParameters 메서드를 이용하여 처리하고 있다.

org.apache.catalina.connector.Request.parseParameters 메서드

1
2
3
4
5
6
7
8
9
10
11
protected void parseParameters() {

...

String enc = getCharacterEncoding();


...
if (enc != null

{
    parameters.setEncoding(enc);

} else {

    parameters.setEncoding("ISO-8859-1");

}
...
}

org.apache.tomcat.util.http.Parameters.processParameters 메서드

1
2
3
4
5
6
7
8
public void processParameters(byte bytes[], int start, int len, String enc) {
...

tmpName.setBytes(bytes, nameStart, nameEnd – nameStart);

tmpValue.setBytes(bytes, valStart, valEnd – valStart);
...

addParam(urlDecode(tmpName, enc), urlDecode(tmpValue, enc));

...
}

위 코드를 보면 알 수 있듯이, 인코딩이 올바르지 않게 설정되면 파라미터에 잘못된 값이 들어감을 알 수 있다. 다음 코드는 URL 디코딩이 잘못되면 어떤 결과가 초래되는지 쉽게 살펴볼 수 있는 예이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
String hangul = "한글";

String[] encodings = new String[] {"EUC-KR", "UTF-8", "ISO8859-1"};
  
for (String encoding1 : encodings) {

    String encoded = URLEncoder.encode(hangul, encoding1);

    System.out.println(encoded);

    System.out.print("\t");
      
    for (String encoding2 : encodings) {

        String decoded = URLDecoder.decode(encoded, encoding2);

        System.out.print(decoded + "\t\t");
    }
    System.out.println("\n");
}

5ea8352df1fc1bc1fb1bb9bae636ec5c

웹에서 여러 인코딩을 지원하려면, 인코딩된 URL 문자열과 사용한 인코딩 정보를 파라미터로 전달 해야 한다. 예를 들어, "/search.nhn?query=%C7%D1%B1%DB&ie=EUC-KR" 과 같이 URL이 설정되어 있다면, ie 파라미터 값을 이용하여 query의 파라미터 값을 URL 디코딩하면 된다. 그리고 가능하다면 Javascript의 encodeURI 메서드 (또는 encodeURIComponent 메서드)를 사용하는 것이 좋다.

Javascript에서의 URL 인코딩

Javascript는 escape, encodeURI, encodeURIComponent 메서드를 이용하여 URL을 인코딩할 수 있다. 이 중 escape 메서드는 A~Z, a~z, 0~9, @*-_+./ 문자가 아니면 유니코드 형식으로 인코딩하는데, ASCII 문자는 %XX, 그 외는 %uXXXX 형태로 인코딩된다. 예를 들어, '한글'을 escape 메서드로 인코딩하면, %uD55C%uAE00으로 인코딩되므로, Tomcat에서 URL 디코딩 시에 문제가 발생하게 된다. 일반적으로 문자열을 URL 인코딩하기 위해서 encodeURI 메서드를 많이 사용하며, :;=?& 문자는 인코딩하지 않는다.

Java의 URLEncoder.encode 메서드와 Javascript의 encodeURI 메서드는 공백(whitespace)을 '%20'으로 인코딩하느냐, '+'로 인코딩하느냐만 다르다. 마지막으로 encodeURIComponent 메서드는 encodeURI 메서드와 유사하지만, :;/=?&도 인코딩한다.

브라우저에서의 EUC-KR 인코딩

EUC-KR 인코딩은 2,350자의 한글만 사용할 수 있다. 그러면 EUC-KR 인코딩으로 이루어진 웹 페이지에서 '똠방각하'와 같은 문자열은 어떻게 처리될까? 브라우저 별로 다국어가 포함된 URL 인코딩 처리하는 방법이 다르다. EUC-KR 인코딩으로 표현 가능한 '한글'을 웹 URL에 넣어 브라우저 인코딩 테스트를 해보면 Internet Explorer, Firefox, Chrome 모두 한글을 '%C7%D1%B1%DB' 로 인코딩한다. 그러나 EUC-KR로 인코딩할 수 없는 '똠방각하' 를 처리할 때는 브라우저마다 결과가 다르다. 브라우저 별 EUC-KR 인코딩 방법을 테스트하기 위해 EUC-KR 인코딩을 사용하는 검색 시스템인 알타비스트를 이용해보기로 한다.

3b154714c4b23edcc47499ba5a3c75ff

브라우저 검색 URL의 p 파리미터 값을 살펴보자.

표 5 브라우저 별 EUC-KR 인코딩 결과

브라우저

인코딩된 값

화면에 표시되는 문자열

Internet Explorer

%26%2346624%3B%B9%E6%B0%A2%C7%CF

&#46624;방각하

Firefox

%A4%D4%A4%A8%A4%C7%A4%B1%B9%E6%B0%A2%C7%CF

ㄸㅗㅁ방각하

Chome

%8Cc%B9%E6%B0%A2%C7%CF

c방각하

Chrome은 EUC-KR에 있는 확장 완성형의 문자를 지원하지 않기 때문에 '똠'을 인코딩할 수 없다. Internet Explorer는 EUC-KR에 없는 문자의 경우 유니코드 포인트 값으로 표현한다. 즉 '똠'의 유니코드 코드 포인트 값인 46624(U+B620)으로 URL 을 인코딩 한다. Firefox는 한글 채움 문자를 이용하여 음절을 표시하고 있다. 한글 채움 문자는 KS X 1001 표준안에 정의되어 있으며, (채움) 초성 중성 종성의 형태로 표시하고, 초성, 중성, 종성의 값이 없는 경우 (채움)으로 표시한다. EUC-KR 인코딩에서는 (채움) 값이 0xA4 0xD4이므로, 다음과 같이 인코딩된다.

표6 EUC-KR로 똠방각하를 인코딩할 때

인코딩

%A4%D4

(채움)

%A4%A8

%A4%C7

%A4%B1

%B9%E6

%B0%A2

%C7%CF

알아두면 좋은 것들

영문 MS Windows는 CP1252, 한글 MS Windows는 MS949가 기본 인코딩이다. 리눅스에서는 LANG 환경 변수에 따라 다르지만, ko, ko_KR, ko_KR.eucKR은 모두 EUC-KR 인코딩이며, ko_KR.UTF-8만 UTF-8 인코딩이다. CentOS의 경우 /etc/sysconfig/i18n에서 시스템 기본 인코딩을 설정할 수 있다. 참고로 i18n은 국제화(internationalization)를 의미하며, l10n은 지역화(localization)을 의미한다. 18과 10이라는 숫자는 i와 n 사이, 또는 l과 n 사이의 글자 수를 의미한다. 요즘 편집기는 여러 인코딩을 처리할 수 있으므로, 보통 문서의 처음에 BOM(Byte Order Mark)이라는 값을 지정하여 인코딩 정보를 저장한다. UTF-8은 0xEF 0xBB 0xBF이며, 나머지 인코딩에 대한 BOM 값은 위키백과(http://en.wikipedia.org/wiki/Byte_order_mark)를 참고하면 좋다.

[1] 유니코드, http://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C

[2] UTF-8, http://ko.wikipedia.org/wiki/UTF-8

[3] 유니코드 정규화,http://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C_%EC%A0%95%EA%B7%9C%ED%99%94

[4] 옛한글, http://ko.wikipedia.org/wiki/%EC%98%9B%ED%95%9C%EA%B8%80

[5] 바이트 순서 표식,http://ko.wikipedia.org/wiki/%EB%B0%94%EC%9D%B4%ED%8A%B8_%EC%88%9C%EC%84%9C_%ED%91%9C%EC%8B%9D




표2 유니코드 범위 목록에서의 한글 관련 범위

이름

처음

개수

한글 자모 (Hangul Jamo)

1100

11FF

256

호환용 한글 자모 (Hangul Compatibility Jamo)

3130

318F

96

한글 자모 확장 A (Hangul Jamo Extended A)

A960

A97F

32

한글 소리 마디 (Hangul Syllables)

AC00

D7AF

11184

한글 자모 확장 B (Hangul Jamo Extended B)

D7B0

D7FF

80


표 3 한글 소리마디에서 초성/중성/종성에 대한 순서 값

초성

중성

종성

초성

중성

종성

0

채움

14

1

15

2

16

3

17

4

18

5

19

 

6

20

 

7

21

  

8

22

  

9

23

  

10

24

  

11

25

  

12

26

  

13

27

  



한글 음절의 코드 포인트 값은 시작 값인 U+AC00에 ((초성 값 x 21) + 중성 값) x 28 + 종성 값을 더하면 된다. 예를 들어, '한'이라는 글자는 'ㅎ', 'ㅏ', 'ㄴ'으로 구성되어 있으며, 각각 18, 0, 4 값을 가지고 있으므로, '한'의 코드 포인트 값은 U+AC00 + ((18 x 21) + 0) x 28 + 4 = U+AC00 + U+295C = U+D55C가 된다. 이를 역으로 생각해 보면, 한글 음절에 대해 초성, 중성, 종성의 분리가 가능하다. 즉 한글 음절의 코드 포인트 값에서 U+AC00을 뺀 값을 ①이라 한다면, 다음과 같이 정리할 수 있다.

  • 의 값을 (21 x 28)로 나눈 몫은 초성
  • 의 값을 (21 x 28)로 나눈 나머지를, 28로 나눈 몫은 중성
  • 의 값을 28로 나눈 나머지는 종성
간단하게 3차원 배열로 생각하면 될듯  [초성][중성][종성]  결국 구하려면 
((초성의 인덱스 *중성의 배열크기) +중성의 인덱스 )*종성의 배열크기 + 종성의 인덱스



유니코드 정규화(Unicode equivalence)

한글 소리 마디와 한글자모, 한글 자모 확장 이렇게 두 개의 코드 영역이 있다는 것은 같은 글자를 표현하는 서로 다른 두 개의 방법이 있다는 것을 말한다. 이것은 한글뿐만 아니라 다른 언어에서도 나타나는 현상이다. 가령 "n"을 표현할 때 U+00F1을 사용할 수도 있고, U+006E (라틴 소문자 "n") 과 U+0303( 결합 틸데 "◌̃")을 연이어 사용하여 표현할 수도 있다. 유니코드 정규화(Unicode equivalence)란 이렇게 연속적인 코드를 사용하여 표현한 어떤 글자를 처리하는 방법을 다루는 명세이다. 유니코드 정규화에는 다음과 같은 네 가지 방법이 있다.

표 4 유니코드 정규화 방법과 예

정규화 방법

NFD

(정준 분해)

Normalization Form Canonical Decomposition

A (U+00C0)  A (U+0041) + ̀ (U+0300)

위 (U+C704)   (U+110B) +  (U+1171)

NFC

(정준 분해한 뒤 다시 정준 결합)

Normalization Form Canonical Composition

A (U+0041) + ̀ (U+0300)  A (U+00C0)

 (U+110B) +  (U+1171)  위 (U+C704)

NFKD

(호환 분해)

Normalization Form Compatibility Decomposition

 (U+FB01)  f (U+0066) + i (U+0069)

NFKC

(호환 분해한 뒤 다시 정준 결합)

Normalization Form Compatibility Composition

 (U+F914),  (U+F95C),  (U+F9BF)   (U+6A02)

이중 한글 처리와 관련된 것은 NFD(소리 마디를 첫가끝 코드로 분해)와 NFC(첫가끝 코드를 소리 마디로 결합)이다.

Java는 유니코드 정규화 기능을 지원하고 있다. 아래 코드는 그 예제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.text.Normalizer;
  
public class NormalizerTest {

    private void printIt(String string) {

        System.out.println(string);

        for (int i = 0; i < string.length(); i++) {

            System.out.print(String.format("U+%04X ", string.codePointAt(i)));
        }
        System.out.println();
    }
  
    @Test
    public void test() {

        String han = "한";

        printIt(han);
          
        String nfd = Normalizer.normalize(han, Normalizer.Form.NFD);

        printIt(nfd);
          
        String nfc = Normalizer.normalize(nfd, Normalizer.Form.NFC);
        printIt(nfc);
    }
     
}

아래는 위의 코드를 실행한 결과이다.

U+D55C
ㅎㅏㄴ
U+1112 U+1161 U+11AB
U+D55C

만약, 아래아 한(e049e1742f7b78edf7fd7b9762fb2523)을 NFC로 만들고자 한다면, 'ㅎ'(U+1112), 'ㆍ'(U+119E), 'ㄴ'(U+11AB)를 결합하면 된다. 옛한글의 경우 글꼴에 따라 출력이 되지 않을 수 있으므로, 옛한글 글꼴을 지원하는 은글꼴 또는 함초롬체를 사용하여야 한다.


'프로그래밍 > 인코딩' 카테고리의 다른 글

java에서 한글 encode  (0) 2014.01.01
by givingsheart 2014. 1. 1. 16:31
package threadFight;

public class main
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Unit unit1 = new Unit();
Thread th = new Thread(unit1);
th.start();
}
}

class Unit implements Runnable
{
public String name = "홍길동";
public int hp = 50;
@Override
public void run()
{
while(this.isLive())
{
// TODO Auto-generated method stub
//랜덤으로 상대에게 타격한다.
int at = (int)(Math.random()*6 ); //0~5
hp-=at;
System.out.println(name + " 님이 " + at + " 데미지로 자해하고 있습니다. hp:" + hp);
}
System.out.println(name + " 님이 뒤졌습니다.");
}
public boolean isLive()
{
return hp >0;
}
}


아..글고,.. 런에이블 편하게 쓸라면...흠.. 멤버 필드로 Thread를 갖고.. 위임 패턴을 적용해볼까?  

class A 라면.. 런에이블 조립해서 run 재정의 하고.. 내부적으로 생성자에서 멤버 필드 스레드 객체를 생성할때.. this(자신)을 
매개변수로 넣으면 스레드는 이제 내 객체(a)를 참조할수 있으니.. start(){ thread.start(); } 처럼 간단하게 사용 가능할듯 .. 
=>문제는.. run()이 퍼블릭 인터페이스로 노출되는점 ㅠㅠ  사용자께서(나?) start()로 사용해 주시길..

public class ddd
{

public static void main(String[] args)
{
// TODO Auto-generated method stub
ChildA a = new ChildA();
ChildB b = new ChildB();
a.start();
b.start();

}

}

abstract class Base
{
protected Thread thread;
}

class ChildA extends Base implements Runnable
{
ChildA()
{
thread = new Thread(this);
}
@Override
public void run()
{
for(int i=0; i< 100; i++)
{
System.out.println(thread.getName());
}
}
public void start()
{
thread.start();
}
}

class ChildB extends Base implements Runnable
{
ChildB()
{
thread = new Thread(this);
}
@Override
public void run()
{
for(int i=0; i< 100; i++)
{
System.out.println(thread.getName());
}
}
public void start()
{
thread.start();
}
}


=>core api에서 제공하는 인터페이스의 사용에 대해 아주 쬐금 감을 잡은듯도 하다.. 상속을 받으면 유연하지 않으니.. 가급적
core api 의 경우 interface를 구현하고 해당 클래스를 멤버 필드로 갖자(상속보단 구성!)

아니면 말고.. 그만 놀고 공부하자  -_-;


ps.멀티 스레딩 관련 볼만한 책들.. 갖고 싶다..




by givingsheart 2014. 1. 1. 16:29


한글,영어,중국어,일본어 등등을 지원하려면 UTF-8 로 하잣! UTF-8이 가장 많이 쓰인다고 한다. (ms949 버렷 -_-)


http://helloworld.naver.com/helloworld/19187



한글의 인코딩 방식

EUC-KR은 KS X 1001과 KS X 1003 표준안의 인코딩 방식이며, CP949(MS949, x-windows-949)는 확장 완성형의 인코딩 방식이다. 그러므로 EUC-KR은 2,350자의 한글, CP949는 11,172자의 한글을 표현할 수 있다. 그러나 Java에서는 CP949와 MS949를 다르게 취급한다. CP949는 IBM에서 처음 지정한 코드 페이지(sun.nio.cs.ext.IBM949)가 기준이고 Microsoft가 제정한 확장 완성형은 MS949(sun.nio.cs.ext.MS949)를 기준이다. 그러므로 Java에서는 CP949와 EUC-KR이 사실상 같으며, 확장 완성형을 사용하기 위해서는 MS949로 지정해야 한다.

유니코드

한글뿐 아니라 일본어와 중국어에도 컴퓨터에서 해당 언어를 표현할 수 있는 독자적인 문자 집합이 있다(KPS-9566, EUC-CN, EUC-TW, EUC-JP, Shift JIS, Big5, GB, HZ 등). 문제는 '어떻게 동시에 한국어, 중국어, 일본어를 표현하느냐'이다. 하나의 문자 집합을 사용하는 문서에서는 이를 동시에 표현할 수 없다(escape sequence를 이용하여 여러 문자 집합을 표현할 수 있으나 이는 널리 쓰이지 않았다).

이런 문제는 유럽어의 문자 집합에도 있었다. 유로화를 나타내는 '€' 기호에는 ISO 8859-15(Latin 9)의 코드 값 중 0xA4이 할당되었으나 ISO 8859-1(Latin 1)의 0xA4 코드에 할당된 문자는 '¤'다. 이 문제를 해결하기 위해 전 세계적으로 사용되는 모든 문자 집합을 하나로 모아 탄생시킨 것이 유니코드이다. ISO 10646 표준에서 UCS(Universal Character Set)을 정의하고 있다. 유니코드 1.0.0은 1991년 8월 제정되었으며, 그 후 약 5년이 지나서야 유니코드 2.0.0에 한글 11,172자가 모두 포함되었다. 현재 버전은 2010년 10월 11일 제정된 6.0이다.

유니코드 값을 나타내기 위해서는 코드 포인트(code point)를 사용하는데, 보통 U+를 붙여 표시한다. 예를 들어, 'A'의 유니코드 값은 U+0041로 표현한다(\u0041로 표기하기도 함). 유니코드는 공식적으로 31비트 문자 집합이지만 현재까지는 21비트 이내로 모두 표현이 가능하다. 유니코드는 논리적으로 평면(plane)이라는 개념을 이용하여 구획을 나누며, 평면 개수는 0번 평면인 기본 다국어 평면(BMP; Basic Multilingual Plane)에서 16번 평면까지 모두 17개이다. 대부분의 문자는 U+0000~U+FFFF 범위에 있는 기본 다국어 평면에 속하며, 일부 한자는 보조 다국어 평면(SMP, Supplementary Multilingual Plane)인 U+10000~U+1FFFF 범위에 속한다. 이 중 한글은 U+1100~U+11FF 사이에 한글 자모 영역, U+AC00~U+D7AF 사이의 한글 소리 마디 영역에 포함된다(자세한 내용은 위키백과의 '유니코드 목록' 내용 참조).

유니코드 인코딩 방식

유니코드의 인코딩 방식으로는 코드 포인트를 코드화한 UCS-2와 UCS-4, 변환 인코딩 형식(UTF, UCS Transformation Format)인 UTF-7, UTF-8, UTF-16, UTF-32 인코딩 등이 있다. 이 중 ASCII와 호환이 가능하면서 유니코드를 표현할 수 있는 UTF-8 인코딩이 가장 많이 사용된다. UTF-8은 코드 포인트 범위에 따라 다음 표에서 보는 바와 같이 인코딩 방식이 다르다.

다음 표는 코드 포인트 범위에 따른 UTF-8 인코딩 방식을 보여준다.

코드 포인트 범위

비트 수

인코딩

U+0000~U+007F

7

그대로 인코딩

U+0080~U+07FF

11

110xxxxx 10xxxxxx

U+0800~U+FFFF

16

1110xxxx 10xxxxxx 10xxxxxx

U+10000~U+1FFFFF

21

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

위의 표에서 xxxx로 표시된 부분에는 원래의 비트 값을 순서대로 적는다. 즉, U+0080을 비트 값으로 표현하면 000 1000 0000인데, 인코딩 방식에 의해 11000010 10000000으로 변환되어, 0xC2 0x80으로 저장된다. 예를 들어, '한글'을 코드 포인트로 표현하면 U+D55C U+AE00인데, 이를 UTF-8 인코딩하면, 0xED 0x95 0x9C 0xEA 0xB8 0x80이 된다.

U+D55C U+AE00

1101 0101 0101 1100 1010 1110 0000 0000            2진수 표현

1110 1101 1001 0101 1001 1100 1110 1010 1011 1000 1000 0000    인코딩 방식에 따라 인코딩

한글 완성형의 코드 포인트 범위는 U+AC00~U+D7AF이므로, UTF-8 인코딩에서 한글은 무조건 3바이트 인코딩이다. 그래서 URL에 파라미터 값이 %ED%95%9C%EA%B8%80과 같이 표시된다면 UTF-8 인코딩일 확률이 높다(ISO8859, EUC-KR, UTF-8 인코딩 중 하나라면 말이다).


'프로그래밍 > 인코딩' 카테고리의 다른 글

자바에서 한글 인코딩  (0) 2014.01.01
by givingsheart 2014. 1. 1. 16:26
자바 보안 관련 블로그




파이썬 보안 문서(자바도 쬐금 들었음)

http://heehiee.codns.com:9000/060611/0_%B8%B6%C0%CC%C5%A9%B7%CE%BC%D2%C7%C1%C6%AE%C0%E2%C1%F6/2002/9%BF%F9%C8%A3/New!%20About/0209-380.pdf




자바에서 보안관련 패키지 

java.security.MassegeDigest :요놈 생성해서,..update() 해서 사용하면 끝~~~ 초간단? 
(생성은 스태틱 메서드인   getInstance (String  algorithm)  매개변수는 "MD5" or "SHA")

이 MessageDigest 클래스는, MD5 또는 SHA 등의 메세지 다이제스트 알고리즘의 기능을 제공합니다. 메세지 다이제스트는, 
임의 사이즈의 데이터를 취득해 고정장의 해시치를 출력하는 안전한 한방향의 해시 기능입니다.

MessageDigest 객체는, 초기화되어 기동됩니다. 데이터는, MessageDigest 객체를 개입시켜 update 메소드를 사용해 처리됩니다. 
reset 메소드를 호출하는 것으로, 임의의 시점에서 다이제스트를 리셋 할 수 있습니다. 갱신 대상의 데이터가 모두 갱신된 시점에서,
digest 메소드의 1 개를 호출하는 것으로, 해시 계산을 종료할 필요가 있습니다.

digest 메소드는, 지정 회수의 갱신에 대해서 1 회 호출하는 것만으로 끝납니다. digest 메소드의 호출이 종료한 뒤, MessageDigest 
객체는 초기화 상태에 리셋 됩니다.

Cloneable 인터페이스는, 자유롭게 구현할 수 있습니다. 클라이언트 어플리케이션은, 복제의 생성을 시행해 CloneNotSupportedException 
를 캐치 하면, 복제의 생성이 가능한가 어떤가를 조사할 수가 있습니다.

MessageDigest md = MessageDigest.getInstance("SHA");

try {
md.update(toChapter1);
MessageDigest tc1 = md.clone();
byte[] toChapter1Digest = tc1.digest();
md.update(toChapter2);
...등
} catch (CloneNotSupportedException cnse) {
throw new DigestException("couldn't make digest of partial content");
 }

********************************************************************

java.security 
클래스 KeyFactory

X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);
Signature sig = Signature.getInstance("DSA");
sig.initVerify(bobPubKey);
sig.update(data);
sig.verify(signature);

*******************************************************************
(RSA 관련 블로그)
http://blog.naver.com/PostView.nhn?blogId=nttkak&logNo=20130239694</p></div>



(추가)

나는 요때부터 보안에도 관심을 가졌었구나.. 하긴 오래전 게임 회사 일할때.. 해킹및 불법 사용자 문제로 고생을 했었지... 실제 서비스를 제공한다고 했을때, 보안이란 문제의 비중은 결코 가볍지 않다.

'프로그래밍 > 보안' 카테고리의 다른 글

jvm의 입장?  (0) 2014.01.02
패킷 암호화 코드 긁어온것 ㅠㅠ  (0) 2014.01.01
by givingsheart 2014. 1. 1. 16:09
| 1 2 3 4 5 6 7 |