2016년 11월 8일 화요일

[EtC] CAL69 Type D




사진을 클릭 하시면 크게 보실 수 있습니다.




온라인 쇼핑몰에서 구입한지 5일만에 커다란 상자에 썰렁하게(?) 도착 했습니다.




뒷면에 설명서도 읽어 보고...




앞면은 이렇게 생겼습니다.




꺼내 보았습니다. 단순한 구성 입니다. 외국인이 칼이라는거 모를까봐 영어로 칼 이라고 써 놨네요.




우선 나이프의 앞면 입니다.




뒷면에는 벨트에 고정 할 수 있는 클립이 있습니다. 




펼쳤을때 사진 입니다. 사진을 돌린다는게 깜박 했네요.




엄지 손가락 부분이 나이프를 펼쳤을때 고정 되는 부분 입니다.

안쪽으로 살짝 눌러 주면 나이프를 접을 수 있습니다.

스프링 없이 나이프를 고정 하여 내구성 면에서 좋은 점수를 주고 싶습니다.






약간 두꺼운 종이를 썰어 보았습니다.

종이를 써는 용도는 아니라서 그런지 잘 썰리는 편은 아니었습니다.

그래도 아웃도어에서 간단히 음식을 써는데는 문제 없을 것으로 판단 됩니다.




전체 길이는 위의 사진과 같습니다.




나이프의 날 모양은 사진과 같습니다.



무게감이나 나이프의 모양, 내구성 등 전체적으로 아웃도어용으로 손색이 없습니다.

녹이 잘 안스는 재질이라고 하는데, 그건 좀더 사용해 봐야 알 거 같습니다.

가격도 1만원 중반대로 나쁜편은 아니었습니다.


2016년 11월 3일 목요일

[C++] Hello World

main.cpp 예제
#include 
#include     /* getpid() 를 사용하기 위해 필요 */
#include     /* rand() 사용하기 위해 필요 */
#include 

#include "libs/testClass.h"  /* 사용자 정의 클래스 */

using namespace std;

/* prototype */
void sayHello(string msg);  /* 테스트용 메서드 */
string sayHello2(string msg); /* 테스트용 메서드2 */
int getRandInt(int maxNum);  /* 랜덤한 숫자를 얻어내기 위한 메서드 */

int main() {
 cout << "PID : " << getpid() << " ==> Hello World!!!" << endl; // prints !!!Hello World!!!

 sayHello("홍길동");
 cout << sayHello2("홍길순") << endl;
 cout << "RAND NUM : " << getRandInt(64) << endl;

 cout << "=====================================" << endl;

 testClass tc = testClass();
 cout << tc.iSay("ho~") << endl;
 cout << tc.youSay("hu~~") << endl;

 return 0;
}

/* 테스트용 메서드 */
void sayHello(string msg){
 cout << msg + "님, 안녕하세요?" << endl;
}

/* 테스트용 메서드2 */
string sayHello2(string msg){
 return msg + "님, 안녕하세요?";
}

/* 랜덤한 숫자를 얻어내기 위한 메서드 */
int getRandInt(int maxNum){
 srand(time(NULL));
 return rand() % maxNum +1;
}
testClass.h 예제
#ifndef TESTCLASS_H_
#define TESTCLASS_H_

#include 
using namespace std;

class testClass {
public:
 testClass();    /* 생성자 */
 virtual ~testClass();  /* 소멸자 */

 string iSay(string msg); /* 내가 말하는 메서드 */
 string youSay(string msg); /* 네가 말하기 메서드 */
};

#endif
testClass.cpp 예제
#include "testClass.h"

/* 생성자 */
testClass::testClass() {
 // TODO Auto-generated constructor stub
 cout << "생성자 호출 됨" << endl;
}

/* 소멸자 */
testClass::~testClass() {
 // TODO Auto-generated destructor stub
 cout << "소멸자 호출 됨" << endl;
}

/* 내가 말하는 메서드 */
string testClass::iSay(string msg){
 return "i say " + msg;
}

/* 네가 말하는 메서드 */
string testClass::youSay(string msg){
 return "you say " + msg;
}

2016년 10월 21일 금요일

[JaVa] AES256 암호화 및 복호화


출처 : http://www.imcore.net/encrypt-decrypt-aes256-c-objective-ios-iphone-ipad-php-java-android-perl-javascript-python/


import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

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


 
/*
 참고 : http://www.imcore.net/encrypt-decrypt-aes256-c-objective-ios-iphone-ipad-php-java-android-perl-javascript-python/
 
 jce patch 적용 되어있어야 하며, commons-codec-1.10.jar 필요 
*/
 
public class AES256Util {

 public static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

 
 /**
  * 일반 문자열을 지정된 키를 이용하여 AES256 으로 암호화
  * @param  String - 암호화 대상 문자열
  * @param  String - 문자열 암호화에 사용될 키
  * @return String - key 로 암호화된  문자열 
  * @exception 
  */
 public static String strEncode(String str, String key) throws java.io.UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
  
  byte[] textBytes = str.getBytes("UTF-8");
  AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
  SecretKeySpec newKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
  Cipher cipher = null;
  cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
  return Base64.encodeBase64String(cipher.doFinal(textBytes));
 }

 
 
 /**
  * 암호화된 문자열을 지정된 키를 이용하여 AES256 으로 복호화
  * @param  String - 복호화 대상 문자열
  * @param  String - 문자열 복호화에 사용될 키
  * @return String - key 로 복호화된  문자열 
  * @exception 
  */ 
 public static String strDecode(String str, String key) throws java.io.UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
  
  byte[] textBytes = Base64.decodeBase64(str);
  //byte[] textBytes = str.getBytes("UTF-8");
  AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
  SecretKeySpec newKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
  return new String(cipher.doFinal(textBytes), "UTF-8");
 }
 
}



사용은 아래 처럼...

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

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


public class aes256EncTest {

 public static void main(String[] args) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {


  String key = "12345678901234567890123456789012";    //key는 16~32자리
  
  AES256Util aes256Util = new AES256Util();
  
  /* XML 문자열 암호화 */
  String encStr = aes256Util.strEncode(xmlStr, key);
  System.out.println("encStr =============> " + encStr);
  
  
  /* XML 문자열 복호화 */
  String decStr = aes256Util.strDecode(encStr, key);
  System.out.println("decStr =============> " + decStr);


 }

}

[JaVa] http 통신 예제 코드


출처 : http://whitegom.tistory.com/26


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;


public class httpGetXmlTest {

 public static void main(String[] args) throws Exception {
  // TODO Auto-generated method stub
  
  URL url = new URL("http://192.168.137.130:8080/exam/xml3/admin");

  // open connection
  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  conn.setDoInput(true);          // 입력스트림 사용
  conn.setDoOutput(true);         // 출력스트림 사용
  conn.setUseCaches(false);       // 캐시사용 안함
  conn.setReadTimeout(30000);     // 타임아웃 : 3초
  conn.setRequestMethod("GET");   // GET or POST ...
        
  StringBuffer sb =  new StringBuffer();

  BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

  for (;;) {
   String line = br.readLine();
   if (line == null)
    break;
   sb.append(line + "\n");
  }

  br.close();
  conn.disconnect();
        
  String getXml = sb.toString();

  System.out.println(sb.toString());        
 }
}

2016년 7월 12일 화요일

[JaVa] byte[] -> String

byte[] mgs; // 어떤 값이 들어 있다 치고...

try {
     System.out.println(new String(mgs, "UTF-8"));
} catch (UnsupportedEncodingException e) {
     e.printStackTrace();
}

2016년 7월 7일 목요일

[SpRiNg] Spring Security 강제 로그인


Spring Security를 적용한 경우 session 에 값만 만들어 준다고 로그인 처리가 되지 않는다.

아래의 코드는 Spring Security 3.2.7.RELEASE 와 4.1.0.RELEASE 에서 쿠키를 이용하여 로그인을 처리 해야 하는 경우에 사용 하였다.

// 사용자의 아이디, 비밀번호, ROLE_ 로 시작 하는 권한 정보를 가지고 온다.
MySessionDataDto mInfo = commonSvc.getMySessionData(userid); 
Authentication authentication = new UsernamePasswordAuthenticationToken(mInfo.getUserid(), mInfo.getUserpw(), AuthorityUtils.createAuthorityList(mInfo.getUserauth()));
   
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(authentication);
HttpSession session = request.getSession(true);
 

// 세션에 필요한 정보를 넣어 준다.
session.setAttribute("userid", mInfo.getUserid());
session.setAttribute("usernm", mInfo.getUsernm());


2016년 6월 16일 목요일

[EtC] mysql 한글 깨지는 경우



my.cnf 파일을 수정 하여 아래의 내용을 넣는다.


[client]
default-character-set = utf8


[mysql]
default-character-set = utf8


[mysqld]
init_connect = SET collation_connection = utf8_general_ci
init_connect = SET NAMES utf8
character-set-server = utf8
collation-server = utf8_general_ci


[mysqldump]
default-character-set = utf8

[EtC] tomcat startup 느려진 경우



INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [190,232] milliseconds.


tomcat startup 이 느려진 이유를 찾기 위해 catalina.log 를 보니, 위와 같은 메세지가 보이는 경우 catalina.sh 파일에 아래와 같이 추가 하도록 한다.

#!/bin/sh

JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"



참고 : tomcat 메모리 할당

#!/bin/sh

export CATALINA_OPTS="-server -Xms8192m -Xmx8192m -XX:PermSize=256M -XX:MaxPermSize=256M -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:+AggressiveOpts"


2016년 6월 2일 목요일

[MySqL] mysql backup script

root@api:/usr/local/apache-tomcat-7.0.64# cat ~/mysql-backup.sh


#!/bin/bash

backupdir='/home/freecatz/MYSQL_BACKUP/'`date +%Y%m%d`
olddir='/home/freecatz/MYSQL_BACKUP/'`date -d "7 day ago" +%Y%m%d`

function FN_DB_BACKUP(){
echo $(date +%H:%M) - $1 DATABASE FULL BACKUP START.  >>  $backupdir/$1.log
mysqldump -uroot -p'qwer1234' $1 > $backupdir/$1.sql
echo $(date +%H:%M) - $1 DATABASE FULL BACKUP FINISH.  >>  $backupdir/$1.log
mysql -uroot -p'qwer1234' -e "SELECT TABLE_SCHEMA, CONCAT(FORMAT(SUM(DATA_LENGTH + INDEX_LENGTH) / (1024*1024), 2), 'MB') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '$1'" | grep -v TABLE_SCHEMA >> $backupdir/$1.log
}


function FN_MK_DIR(){
mkdir -p $backupdir

if [ -d $olddir ]; then
rm -rf $olddir
fi
}


if [ ! -d $backupdir ]; then
FN_MK_DIR
fi


FN_DB_BACKUP DBTEST1
FN_DB_BACKUP DBTEST2
FN_DB_BACKUP DBTEST3


crontab 에 주기적으로 실행 시켜 두면 된다.

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

00 23   * * *   root    /root/mysql-backup.sh
#

2016년 5월 26일 목요일

[Qt] String to QDate

QDate dt = QDate::fromString(ui->dateEdit->text(), "yyyy-MM-dd");

    switch(dt.dayOfWeek()){
       case 1:
            qInfo() << ui->dateEdit->text() << " 월요일 입니다.";
            break;
        case 2:
            qInfo() << ui->dateEdit->text() << " 화요일 입니다.";
            break;
        case 3:
            qInfo() << ui->dateEdit->text() << " 수요일 입니다.";
            break;
        case 4:
            qInfo() << ui->dateEdit->text() << " 목요일 입니다.";
            break;
        case 5:
            qInfo() << ui->dateEdit->text() << " 금요일 입니다.";
            break;
        case 6:
            qInfo() << ui->dateEdit->text() << " 토요일 입니다.";
            break;
        case 7:
            qInfo() << ui->dateEdit->text() << " 일요일 입니다.";
            break;
    }