NFC Tag 저장용량

개발/Note 2020. 5. 29. 10:06
반응형
반응형

'개발 > Note' 카테고리의 다른 글

NFC Xcode 설정  (0) 2020.05.29
NFC (Near Field Communication)  (0) 2020.05.29
NDEF  (0) 2020.05.29
Mifare  (0) 2020.05.29
QR 코드 결제 타입  (0) 2020.05.29
블로그 이미지

SKY STORY

,

NDEF

개발/Note 2020. 5. 29. 10:02
반응형

목차 

1. NDEF

NDEF(NFC Data exchange Format)는 NFC를 이용한 데이터 통신에서 사용하는 "데이터 교환 형식"이다. 대부분의 NFC 태그는 NDEF 형식으로 저장된 데이터를 전송하는 passive elements로 작동한다. 우리가 폰을 이용해서 NFC 태그에 접촉하면, 애플리케이션은 NDEF 데이터를 읽는다.

 

2. NDEF 메시지와 NDEF 레코드

NDEF 메시지는 하나 이상의 NDEF 레코드로 구성된다. NDEF 메시지가 인캡슐할 수 있는 레코드의 갯수는 애플리케이션과 태그 타입에 따라 다르다. NDEF 레코드는 "Header"와 "PayLoad"로 구성된다 아래 그림은 NDEF의 메시지 구성이다.

 

 

아래는 NFC Tag로 부터 읽은 데이터의 hexa code의 예제다. "joinc.com"을 전송했다.

1

 

 

03 0e d1 01 0a 55 03 6a 6f 69 6e 63 2e 63 6f 6d 0a

 

 

 

 

  • 03 : 레코드의 타입이다. NDEF 레코드는 03을 사용한다.
  • 0e : 페이로드의 길이다. 단위는 바이트다.
  • d1 : 가변길이 레코드다. 여기에 담고 있는 정보를 아래에 정리했다.1





    d1 을 바이너리 값으로 변환하면 11010001


  • MB = 1 : 이 레코드는 NDEF 메시지의 첫번째 레코드다.
  • ME = 1 : NDEF 메시지의 마지막 레코드다. 이 값이 0이면 아직 레코드가 더 남아있음을 의미한다.
  • CF = 0 : chunked 메시지가 아니다.
  • SR = 1 : 짧은 레코드인지 아닌지. 레코드가 페이로드를 가지지 않는다면 0을 설정한다.
  • IL = 0 : ID Length를 설정할지를 결정한다. 값이 1 이면 ID_LENGTH 필드가 헤더에 1 옥텟의 크기로 설정된다.
  • TNF = 001 : Type 필드의 값을 명시한다. 0x01은 NFC Forum webll-known type이다. 

  • 01 (Type Length) : TYPE_LENGTH 필드는 8-bit 부호없는 정수형으로 TYPE 필드의 길이를 명시한다. TNF가 0x00, 0x05, 0x06이면 항상 0이다.
  • 0a (Payload Length) : 부호없는 integer 타입이다. Payload length 필드의 크기는 SR flag에 의해서 결정된다.
  • 55 : 페이로드의 데이터 타입이다. ASCII 테이블에서 55는 'U'로, URL 타입의 데이터를 의미한다.
  • 03 : 0x03은 URI identifity다.("http://")
  • Payload : 6a 6f 69 6e 63 2e 63 6f 6d 0a (joinc.com)

 

 

3. 참고

 

 

출처 : https://www.joinc.co.kr/w/man/12/NDEF#toc

반응형

'개발 > Note' 카테고리의 다른 글

NFC (Near Field Communication)  (0) 2020.05.29
NFC Tag 저장용량  (0) 2020.05.29
Mifare  (0) 2020.05.29
QR 코드 결제 타입  (0) 2020.05.29
Base64 encode / decode in C++  (0) 2020.05.29
블로그 이미지

SKY STORY

,

Mifare

개발/Note 2020. 5. 29. 10:01
반응형

1. 개요

네덜란드 NXP반도체[1]의 RF 기술. 이용하는 주파수는 13.56MHz로, 국제표준 규격인 ISO/IEC 14443 Type A와 일부 호환된다. 원래는 Mikron에서 개발한 것이라 이름도 Mikron Fare Collecting System의 두문자어로 MIFARE가 되었는데, 이 기술을 필립스가 현질해서 관련 제품을 생산하기 시작했다.

 

2. 종류

MIFARE 카드는 스마트카드의 일종이지만, 가장 처음에 등장한 MIFARE Classic 1K/4K 카드는 안테나가 달린 외장 메모리였다. 암호화같은 건 정말 팬티 한 장 걸친 수준으로만 해 놓고, 단말기에 접촉해서 정보를 읽고 쓰는 것만 가능하게 만든 것이다. 따라서 보안성이 떨어진다. 이름에서 알 수 있듯이 1K는 1,024바이트, 4K는 4,096바이트를 저장할 수 있다. 유패스가 MIFARE Classic 1K를 이용해서 세계 최초로 상용화된 교통카드다. 대경교통카드도 MIFARE Classic이다. 아예 칩셋까지 NXP 제품을 이용 중. 유패스는 일부 카드만 NXP 제품이다.

일회용으로 쓰기엔 Classic도 오버스펙이라고 해서 MIFARE Ultralight와 MIFARE Ultralight C도 나와 있다. Ultralight는 저장 용량도 512바이트에 암호화 없이 생으로 정보를 기록한다(...) Ultralight C는 보안을 눈꼽만큼 신경써서, 192바이트의 저장 용량에 Triple DES를 올려서 나왔다. 둘 다 일회용 RF 티켓에 사용할 목적으로 개발되었다. 하지만 간혹 울트라라이트를 올려서 나오는 NFC 공태그도 보인다. 대표적으로 LG전자 옵티머스 LTE TAG와 옵티머스 G옵티머스 뷰2 박스에 번들로 들어갔던 LG Tag+(...)가 있다.

가장 대중적으로 쓰이는 것 중에 MIFARE DESFire가 있다. NFC 리더기로 읽어보면 간혹 카드 종류를 MIFARE SmartMX라고도 읽는다. ISO/IEC 14443 표준에 맞는 모델로, 카드 내부에 8051 마이크로프로세서를 탑재하고 Triple DES와 AES를 올려서 나왔다. 티머니와 OysterOV-Chipkaart 등에 절찬리 이용 중. 문제는 이 모델이 2011년에 해킹되었다는 것(...) 후속작으로 보안이 강화되고 DESFire와 하위호환이 되는 MIFARE DESFire EV1이 나왔다.

MIFARE Classic의 보안 수준이 허접한 관계로, 강화된 보안 모듈을 끼워넣은 MIFARE Plus가 나왔다. 메모리는 2K/4K 두 종류로 나왔고 128비트 암호화를 지원하는 듯.

한국은 ISO/IEC 14443기반의 대한민국 표준규격인 KS X 6924 표준으로 정하면서 MIFARE에서 벗어나게 되었다.

 

출처 : https://namu.wiki/w/MIFARE

 

2020/12/16 - [개발노트] - Code 128 Barcode의 Check Digit 계산방법

2020/12/15 - [iOS/Tips] - 디버깅 차단 처리 (Anti Debug)

2020/12/14 - [iOS/Tips] - bundle id 알아내기

2020/12/12 - [AI/Algorithm] - 2D 충돌처리

2020/12/11 - [iOS/Swift] - UIViewController 스위칭

2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)

2020/12/11 - [개발노트] - 특수문자 발음

2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (2/2)

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (1/2)

2020/12/10 - [iOS/Tips] - Custom UserAgent 설정

2020/12/10 - [iOS/Tips] - CocoaPods 설치 및 제거

2020/12/10 - [iOS/Tips] - Clang diagnostic 경고 무시하기

2020/12/10 - [개발노트] - Bluetooth UUID

2020/12/08 - [개발노트] - 모바일 앱 메모리덤프 이슈 해결방법

 

반응형

'개발 > Note' 카테고리의 다른 글

NFC Tag 저장용량  (0) 2020.05.29
NDEF  (0) 2020.05.29
QR 코드 결제 타입  (0) 2020.05.29
Base64 encode / decode in C++  (0) 2020.05.29
iPhone SDK location on hard drive  (0) 2020.05.29
블로그 이미지

SKY STORY

,

클로저(Closure)

개발/iOS 2020. 5. 29. 09:49
반응형

클로저(Closure)

  • 클로저(closure)는 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것을 가르킨다. 클로저는 자바스크립트를 이용한 고난이도의 테크닉을 구사하는데 필수적인 개념으로 활용된다.
  • 예제 코드
function outter(){
    var title = 'coding everybody'; // 외부 함수
    return function(){  // 내부 함수
        alert(title);
    }
}
inner = outter(); // 결과값이 없다.
inner(); // 실행 결과는 alert(title);

 

  • 클로저란 내부함수가 외부함수의 지역변수에 접근 할 수 있고, 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성을 의미한다.

 

클로저를 이용해서 private Method 흉내내기

  • 아래는 프라이빗 함수와 변수에 접근하는 퍼블릭 함수를 정의할 수 있는 클로저를 사용하는 방법을 보여주는 코드가 있다. 이렇게 클로저를 사용하는 것을 모듈 패턴이라 한다.
var counter = (function() { // 익명 함수 안에서 만들어진다
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return { // Return 객체
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  };
})();

console.log(counter.value()); // logs 0
counter.increment();
counter.increment();

// 클로져 바인딩 시키기
function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

  for (var i = 0; i < helpText.length; i++) {
    (function() {
       var item = helpText[i];
       document.getElementById(item.id).onfocus = function() {
         showHelp(item.help);
       }
    })(); // 익명 클로저를 사용하여 바인딩할 수 있다.
  }
}

setupHelp();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1

 

Let 키워드 사용하기

  • let 키워드를 사용하면 블록 범위 변수를 바인딩함으로써 추가적인 클로저를 사용하지 않아도 된다.
function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

  for (var i = 0; i < helpText.length; i++) {
    let item = helpText[i];
    document.getElementById(item.id).onfocus = function() {
      showHelp(item.help);
    }
  }
}

setupHelp();

 

Reference

 

 

2020/05/29 - [개발노트] - QR 코드 결제 타입

2020/05/29 - [iOS/Objective-C] - Objective-C Block Syntax

2020/05/29 - [iOS/Objective-C] - Detect permission of camera in iOS

2020/05/29 - [iOS/Swift] - WKWebView에서 history back 처리

2020/05/29 - [iOS/Objective-C] - OpenGL ES View Snapshot

2020/05/29 - [iOS/Objective-C] - Merge two different images in swift

2020/05/29 - [프로그래밍/C, C++] - Base64 encode / decode in C++

2020/05/29 - [OS/Mac OS X] - iPhone SDK location on hard drive

2020/05/29 - [iOS/Objective-C] - NSString <-> CBUUID 변환

2020/05/29 - [개발노트] - HTTP Content-Type

2020/05/28 - [iOS/Swift] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data 변환

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

반응형

'개발 > iOS' 카테고리의 다른 글

WKWebView  (0) 2020.06.01
네비게이션바 투명 처리  (0) 2020.05.29
Objective-C Block Syntax  (0) 2020.05.29
Detect permission of camera in iOS  (0) 2020.05.29
WKWebView에서 history back 처리  (0) 2020.05.29
블로그 이미지

SKY STORY

,
반응형
반응형

'개발 > Note' 카테고리의 다른 글

NDEF  (0) 2020.05.29
Mifare  (0) 2020.05.29
Base64 encode / decode in C++  (0) 2020.05.29
iPhone SDK location on hard drive  (0) 2020.05.29
HTTP Content-Type  (0) 2020.05.29
블로그 이미지

SKY STORY

,
반응형
typedef 로 타입으로 만들기
typedef RETURN_TYPE (^NAME)(PARAMETERS...);

정의 예제(Definition Example):
typedef void (^SomeHandler)(NSError *error);

구현 예제(Implementation Example):
- (void)someWorkWithCompletion:(SomeHandler)handler {
  ...
}
이름이 리턴 타입 뒤에, 즉 중간에 끼어 있기 때문에 많이 헷갈린다. 



바로 Parameter Field 로 정의하기
fieldName:(RETURN_TYPE (^)(PARAMETERS...))parameterName

정의 예제(Definition Example):
- (void)someMethodWithCompletion:(void (^)(NSData *data))completionHandler;

구현 예제(Implementation Example):
[someClass someMethodwithCompletion:^(NSData *data) {
  ...
}];



Property로 정의하기
RETURN_TYPE (^)(PARAMETERS...)

정의 예제(Definition Example):
@property (nonatomic, strong) void (^completionHandler)(NSData *data);

구현 예제(Implementation Example):
someClass.completionHandler = ^(NSData *data) {
  ...
};
프로퍼티로 정의하는 경우에도 이름이 가운데에 끼어서 좀 불안한(?) 모양세다.



변수로 생성하기
RETURN_TYPE (^BLOCK_NAME)(PARAMETER_TYPES...) = ^RETURN_TYPE(PARAMETERS...) { ... };

구현 예제(Implementation Example):
void (^someBlock)(NSData *) = ^void(NSData *data) {
  ...
};

[obj methodUsingBlock:someBlock];
[obj anotherMethodUsingBlock:someBlock];
만약 블럭을 여러 곳에서 공통적으로 쓴다면 변수 등으로 정의해서 참조 할 수 있다.


블럭 외부의 변수를 블럭 내부에서 세팅하기
Swift 클로져의 경우는 별 상관 없는데 Objective-C 블럭의 경우 외부 변수에 뭔가를 쓰는 것은 기본적으로 금지되어 있다. (즉 읽기만 가능하다.) 이를 쓰기 가능하게 풀려면 '__block' 을 쓰려는 변수 선언 앞에 달아주면 된다. 아래 코드는 GCD Dispatch 에서 사용하는 예이다.
__block int result = 0;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  ....
  result = [some workAndResult];
});

 

2020/05/29 - [iOS/Objective-C] - Detect permission of camera in iOS

2020/05/29 - [iOS/Swift] - WKWebView에서 history back 처리

2020/05/29 - [iOS/Objective-C] - OpenGL ES View Snapshot

2020/05/29 - [iOS/Objective-C] - Merge two different images in swift

2020/05/29 - [프로그래밍/C, C++] - Base64 encode / decode in C++

2020/05/29 - [OS/Mac OS X] - iPhone SDK location on hard drive

2020/05/29 - [iOS/Objective-C] - NSString <-> CBUUID 변환

2020/05/29 - [개발노트] - HTTP Content-Type

2020/05/28 - [iOS/Swift] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data 변환

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

 

반응형

'개발 > iOS' 카테고리의 다른 글

네비게이션바 투명 처리  (0) 2020.05.29
클로저(Closure)  (0) 2020.05.29
Detect permission of camera in iOS  (0) 2020.05.29
WKWebView에서 history back 처리  (0) 2020.05.29
OpenGL ES View Snapshot  (0) 2020.05.29
블로그 이미지

SKY STORY

,
반응형
@import AVFoundation;

NSString *mediaType = AVMediaTypeVideo;
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
if(authStatus == AVAuthorizationStatusAuthorized) {
  // do your logic
} else if(authStatus == AVAuthorizationStatusDenied){
  // denied
} else if(authStatus == AVAuthorizationStatusRestricted){
  // restricted, normally won't happen
} else if(authStatus == AVAuthorizationStatusNotDetermined){
  // not determined?!
  [AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {
    if(granted){
      NSLog(@"Granted access to %@", mediaType);
    } else {
      NSLog(@"Not granted access to %@", mediaType);
    }
  }];
} else {
  // impossible, unknown authorization status
}
반응형

'개발 > iOS' 카테고리의 다른 글

클로저(Closure)  (0) 2020.05.29
Objective-C Block Syntax  (0) 2020.05.29
WKWebView에서 history back 처리  (0) 2020.05.29
OpenGL ES View Snapshot  (0) 2020.05.29
Merge two different images in swift  (0) 2020.05.29
블로그 이미지

SKY STORY

,
반응형

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

네이티브에서 직접 처리할 경우 canGoBack, webView.goBack 함수를 직접 호출하면 되지만 웹에서 뒤로가기를 할 경우 네이티브에 다음과 같이 선언하여 처리하도록 한다.

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        
        guard let url = navigationAction.request.url else {
            decisionHandler(.cancel)
            return
        }
        
        if(navigationAction.navigationType == .backForward) {
            if navigationAction.request.url != nil {
                if webView.canGoBack {
                    print ("Can go back")
                    webView.goBack()
                    //webView.reload()
                    decisionHandler(.cancel)
                    return
                } else {
                    print ( "Can't go back")
                }
            }
        }
        
        // 생략 ~
}

 

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

2020/05/29 - [iOS/Objective-C] - OpenGL ES View Snapshot

2020/05/29 - [iOS/Objective-C] - Merge two different images in swift

2020/05/29 - [프로그래밍/C, C++] - Base64 encode / decode in C++

2020/05/29 - [OS/Mac OS X] - iPhone SDK location on hard drive

2020/05/29 - [iOS/Objective-C] - NSString <-> CBUUID 변환

2020/05/29 - [개발노트] - HTTP Content-Type

2020/05/28 - [iOS/Swift] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data 변환

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

반응형

'개발 > iOS' 카테고리의 다른 글

Objective-C Block Syntax  (0) 2020.05.29
Detect permission of camera in iOS  (0) 2020.05.29
OpenGL ES View Snapshot  (0) 2020.05.29
Merge two different images in swift  (0) 2020.05.29
NSString <-> CBUUID 변환  (0) 2020.05.29
블로그 이미지

SKY STORY

,

OpenGL ES View Snapshot

개발/iOS 2020. 5. 29. 09:24
반응형
// IMPORTANT: Call this method after you draw and before -presentRenderbuffer:.
- (UIImage*)snapshot:(UIView*)eaglview
{
    GLint backingWidth, backingHeight;
 
    // Bind the color renderbuffer used to render the OpenGL ES view
    // If your application only creates a single color renderbuffer which is already bound at this point,
    // this call is redundant, but it is needed if you're dealing with multiple renderbuffers.
    // Note, replace "_colorRenderbuffer" with the actual name of the renderbuffer object defined in your class.
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, _colorRenderbuffer);
 
    // Get the size of the backing CAEAGLLayer
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
 
    NSInteger x = 0, y = 0, width = backingWidth, height = backingHeight;
    NSInteger dataLength = width * height * 4;
    GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));
 
    // Read pixel data from the framebuffer
    glPixelStorei(GL_PACK_ALIGNMENT, 4);
    glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
 
    // Create a CGImage with the pixel data
    // If your OpenGL ES content is opaque, use kCGImageAlphaNoneSkipLast to ignore the alpha channel
    // otherwise, use kCGImageAlphaPremultipliedLast
    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast,
                                    ref, NULL, true, kCGRenderingIntentDefault);
 
    // OpenGL ES measures data in PIXELS
    // Create a graphics context with the target size measured in POINTS
    NSInteger widthInPoints, heightInPoints;
    if (NULL != UIGraphicsBeginImageContextWithOptions) {
        // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
        // Set the scale parameter to your OpenGL ES view's contentScaleFactor
        // so that you get a high-resolution snapshot when its value is greater than 1.0
        CGFloat scale = eaglview.contentScaleFactor;
        widthInPoints = width / scale;
        heightInPoints = height / scale;
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale);
    }
    else {
        // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
        widthInPoints = width;
        heightInPoints = height;
        UIGraphicsBeginImageContext(CGSizeMake(widthInPoints, heightInPoints));
    }
 
    CGContextRef cgcontext = UIGraphicsGetCurrentContext();
 
    // UIKit coordinate system is upside down to GL/Quartz coordinate system
    // Flip the CGImage by rendering it to the flipped bitmap context
    // The size of the destination area is measured in POINTS
    CGContextSetBlendMode(cgcontext, kCGBlendModeCopy);
    CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, widthInPoints, heightInPoints), iref);
 
    // Retrieve the UIImage from the current context
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
 
    UIGraphicsEndImageContext();
 
    // Clean up
    free(data);
    CFRelease(ref);
    CFRelease(colorspace);
    CGImageRelease(iref);
 
    return image;
}

 

2020/05/29 - [iOS/Objective-C] - Merge two different images in swift

2020/05/29 - [프로그래밍/C, C++] - Base64 encode / decode in C++

2020/05/29 - [OS/Mac OS X] - iPhone SDK location on hard drive

2020/05/29 - [iOS/Objective-C] - NSString <-> CBUUID 변환

2020/05/29 - [개발노트] - HTTP Content-Type

2020/05/28 - [iOS/Swift] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data 변환

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

 

반응형
블로그 이미지

SKY STORY

,
반응형
UIImage *image1 = [UIImage imageNamed:@"image1.png"];
UIImage *image2 = [UIImage imageNamed:@"image2.png"];

CGSize size = CGSizeMake(image1.size.width, image1.size.height + image2.size.height);

UIGraphicsBeginImageContext(size);

[image1 drawInRect:CGRectMake(0,0,size.width, image1.size.height)];
[image2 drawInRect:CGRectMake(0,image1.size.height,size.width, image2.size.height)];

UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

//Add image to view
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, finalImage.size.width, finalImage.size.height)];
imageView.image = finalImage;
[self.view addSubview:imageView];

 

2020/05/29 - [프로그래밍/C, C++] - Base64 encode / decode in C++

2020/05/29 - [OS/Mac OS X] - iPhone SDK location on hard drive

2020/05/29 - [iOS/Objective-C] - NSString <-> CBUUID 변환

2020/05/29 - [개발노트] - HTTP Content-Type

2020/05/28 - [iOS/Swift] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data 변환

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

2020/05/19 - [iOS/Tips] - Bitbucket Carthage 사용

반응형

'개발 > iOS' 카테고리의 다른 글

WKWebView에서 history back 처리  (0) 2020.05.29
OpenGL ES View Snapshot  (0) 2020.05.29
NSString <-> CBUUID 변환  (0) 2020.05.29
SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제 (1/2)  (0) 2020.05.28
Array <-> Data 변환  (0) 2020.05.26
블로그 이미지

SKY STORY

,
반응형
Base 64 encode / decode in c++

/*
* Base64 encoding/decoding (RFC1341)
* Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/

// 2016-12-12 - Gaspard Petit : Slightly modified to return a std::string 
// instead of a buffer allocated with malloc.

#include <string>

static const unsigned char base64_table[65] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/**
* base64_encode - Base64 encode
* @src: Data to be encoded
* @len: Length of the data to be encoded
* @out_len: Pointer to output length variable, or %NULL if not used
* Returns: Allocated buffer of out_len bytes of encoded data,
* or empty string on failure
*/
std::string base64_encode(const unsigned char *src, size_t len)
{
    unsigned char *out, *pos;
    const unsigned char *end, *in;

    size_t olen;

    olen = 4*((len + 2) / 3); /* 3-byte blocks to 4-byte */

    if (olen < len)
        return std::string(); /* integer overflow */

    std::string outStr;
    outStr.resize(olen);
    out = (unsigned char*)&outStr[0];

    end = src + len;
    in = src;
    pos = out;
    while (end - in >= 3) {
        *pos++ = base64_table[in[0] >> 2];
        *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
        *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
        *pos++ = base64_table[in[2] & 0x3f];
        in += 3;
    }

    if (end - in) {
        *pos++ = base64_table[in[0] >> 2];
        if (end - in == 1) {
            *pos++ = base64_table[(in[0] & 0x03) << 4];
            *pos++ = '=';
        }
        else {
            *pos++ = base64_table[((in[0] & 0x03) << 4) |
                (in[1] >> 4)];
            *pos++ = base64_table[(in[1] & 0x0f) << 2];
        }
        *pos++ = '=';
    }

    return outStr;
}



static const int B64index[256] = { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62, 63, 62, 62, 63, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,
7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,
0,  0,  0, 63,  0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 };

std::string b64decode(const void* data, const size_t len)
{
    unsigned char* p = (unsigned char*)data;
    int pad = len > 0 && (len % 4 || p[len - 1] == '=');
    const size_t L = ((len + 3) / 4 - pad) * 4;
    std::string str(L / 4 * 3 + pad, '\0');

    for (size_t i = 0, j = 0; i < L; i += 4)
    {
        int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
        str[j++] = n >> 16;
        str[j++] = n >> 8 & 0xFF;
        str[j++] = n & 0xFF;
    }
    if (pad)
    {
        int n = B64index[p[L]] << 18 | B64index[p[L + 1]] << 12;
        str[str.size() - 1] = n >> 16;

        if (len > L + 2 && p[L + 2] != '=')
        {
            n |= B64index[p[L + 2]] << 6;
            str.push_back(n >> 8 & 0xFF);
        }
    }
    return str;
}

 

출처 : github.com/gaspardpetit/base64/

 

2020/05/29 - [OS/Mac OS X] - iPhone SDK location on hard drive

2020/05/29 - [iOS/Objective-C] - NSString <-> CBUUID 변환

2020/05/29 - [개발노트] - HTTP Content-Type

2020/05/28 - [iOS/Swift] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data 변환

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

2020/05/19 - [iOS/Tips] - Bitbucket Carthage 사용

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (3/3) - 메모리 덤프

 

반응형

'개발 > Note' 카테고리의 다른 글

Mifare  (0) 2020.05.29
QR 코드 결제 타입  (0) 2020.05.29
iPhone SDK location on hard drive  (0) 2020.05.29
HTTP Content-Type  (0) 2020.05.29
HMAC SHA256  (0) 2020.05.28
블로그 이미지

SKY STORY

,
반응형

Device SDKs :

/Developer/Platforms/iPhoneOS.platform/Developer/SDKs

 

Simulator:

/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs

/Library/Developer/CoreSimulator/Profiles/Runtimes

 

Templates :

Apple stores the default Templates that come with the app here:

/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates

 

You can add your own custom Templates to one of the standard Library folders, most likely you want "per user", which is here:

~/Library/Developer/Xcode/Templates

 

Provisioning Profiles:

/Users/[ 사용자 계정 ]/Library/MobileDevice/Provisioning\ Profiles

 

Xcode Products :

/Users/[ 사용자 계정 ]/Library/Developer/Xcode/Products

 

IPSW location in Mac OS X

~/Library/iTunes/iPhone\ Software\ Updates

 

IPSW location in Windows

Windows XP: \Documents and Settings\username\Application Data\Apple Computer\iTunes\iPhone Software Updates

Windows Vista & Windows 7: \Users\username\AppData\Roaming\Apple Computer\iTunes\iPhone Software Updates

Windows 8 & Windows 10: \Users\USERNAME\AppData\Roaming\Apple Computer\iTunes\

 

Email Downloads :

/Users/[ 사용자 계정 ]/Library/Containers/com.apple.mail/Data/Library/Mail\ Downloads

 

Derived Data

/Users/[ 사용자 계정 ]/Library/Developer/Xcode/DerivedData

 

Archives

/Users/[ 사용자 계정 ]/Library/Developer/Xcode/Archives

 

Simulator Components

/Library/Developer/CoreSimulator/Profiles/Runtimes

 

Provisioning Profiles:

/Users/[ 사용자 계정 ]/Library/MobileDevice/Provisioning\ Profiles

 

2020/05/29 - [iOS/Objective-C] - NSString <-> CBUUID 변환

2020/05/29 - [개발노트] - HTTP Content-Type

2020/05/28 - [iOS/Swift] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data 변환

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

2020/05/19 - [iOS/Tips] - Bitbucket Carthage 사용

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (3/3) - 메모리 덤프

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (2/3) - Mac OS X 환경 구축

반응형

'개발 > Note' 카테고리의 다른 글

QR 코드 결제 타입  (0) 2020.05.29
Base64 encode / decode in C++  (0) 2020.05.29
HTTP Content-Type  (0) 2020.05.29
HMAC SHA256  (0) 2020.05.28
gdb 사용  (0) 2020.05.19
블로그 이미지

SKY STORY

,
반응형

NSString -> CBUUID

NSString *string = [@"233R194013780790" toUUID];
CBUUID *harexUUID = [CBUUID UUIDWithString:string];
// 결과 :
// 32333352-3139-3430-3133-373830373930

 

CBUUID -> NSString

// 32333352-3139-3430-3133-373830373930
NSString *uuidString = [harexUUID representativeString];
NSString *tid = [harexUUID toString];
// 결과 :
// 233R194013780790

 

관련 함수 :

// String to Hexadecimal String
-(NSString *)toHex {
    char *utf8 = (char *)[self UTF8String];
    NSMutableString *hex = [NSMutableString string];
    while ( *utf8 ) {
        [hex appendFormat:@"%02X" , *utf8++ & 0x00FF];
    }
    return [NSString stringWithFormat:@"%@", hex];
}

// Hexadecimal String to NSData
-(NSData *)hex2Data {
    NSMutableData *stringData = [[NSMutableData alloc] init];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    int i;
    for (i=0; i < [self length] / 2; i++) {
        byte_chars[0] = [self characterAtIndex:i*2];
        byte_chars[1] = [self characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [stringData appendBytes:&whole_byte length:1];
    }
    return stringData;
}

-(CBUUID *)toCBUUID {
    if (NO == [self isValidUUID]) {
        NSLog(@"포멧 비정상.");
        return nil;
    }
    return [CBUUID UUIDWithString:self];
}

-(BOOL)isValidUUID {
    return (BOOL)[[NSUUID alloc] initWithUUIDString:self];
}

// 문자열을 hex로 변경한뒤 UUID포멧으로 변경
-(NSString *)toUUID {
    NSString *string = self;
    if (string.length < 16) {
        NSString *spaceString = @"";
        for (NSInteger i=0; i<(16 - string.length); ++i) {
            spaceString = [spaceString stringByAppendingString:@" "];
        }
        // 길이가 작을 경우 앞쪽에 공백추가
        //string = [NSString stringWithFormat:@"%@%@", spaceString, self];

        // 길이가 작을 경우 뒤쪽에 공백추가
        string = [NSString stringWithFormat:@"%@%@", self, spaceString];
    }
    
    NSData *data = [string toData];
    NSUInteger bytesToConvert = [data length];
    const unsigned char *uuidBytes = [data bytes];
    NSMutableString *outputString = [NSMutableString stringWithCapacity:16];
    
    for (NSUInteger currentByteIndex = 0; currentByteIndex < bytesToConvert; currentByteIndex++) {
        switch (currentByteIndex) {
            case 3:
            case 5:
            case 7:
            case 9:[outputString appendFormat:@"%02X-", uuidBytes[currentByteIndex]]; break;
            default:[outputString appendFormat:@"%02X", uuidBytes[currentByteIndex]];
        }
        //SLog(@"%@", outputString);
    }

 

 

 

2020/05/29 - [개발노트] - HTTP Content-Type

2020/05/28 - [iOS/Swift] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data 변환

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

2020/05/19 - [iOS/Tips] - Bitbucket Carthage 사용

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (3/3) - 메모리 덤프

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (2/3) - Mac OS X 환경 구축

 

반응형

'개발 > iOS' 카테고리의 다른 글

OpenGL ES View Snapshot  (0) 2020.05.29
Merge two different images in swift  (0) 2020.05.29
SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제 (1/2)  (0) 2020.05.28
Array <-> Data 변환  (0) 2020.05.26
UserAgent 변경/추가  (0) 2020.05.25
블로그 이미지

SKY STORY

,

HTTP Content-Type

개발/Note 2020. 5. 29. 08:53
반응형

HTTP는 하이퍼텍스트 통신 프로토콜으로 서버와 클라이언트가 서로 통신하기 위하여 요청과 응답을 받는다.

이때 클라이언트가 서버에게 요청할 때 보내는 데이터 유형과 어떻게 보내야 올바른지 알아보자.

REST 클라이언트 앱인 Postman은 다음과 같은 Content-Type을 제공한다.

일반적인 HTML 폼으로 전송할 때는 x-www-form-urlencoded 또는 multipart/form-data로 전송된다고 알고 있다.

혹시 모르고 있었더라도 걱정하지 말아라. 이제 알았으면 된거다.

중요한 것은 왜 요청 바디가 raw일 때 text/plain, application/json, application/xml등을 선택할 수 있는지를 아는 것이다.

Content-Type 헤더

우리가 중점적으로 알아보아야 할 것은 multipart/form-data, x-www-form-urlencoded, application/json이다.

application/json

대부분의 API에서 활용하는 Content-Type 헤더로써 application/json으로 페이로드와 함께 HTTP 요청을 하게 되면 서버가 JSON 타입으로 변환해서 사용한다.

const data = {
    key1: 'foo',
    key2: 'bar'
}

axios({
    method: 'post',
    url: 'https://localhost:8080',
    headers: {
        'Content-Type': 'application/json'
    },
    data: data
}).then((res) => {
    // handle success
}).catch((err) => {
    // handle error
}).then(() => {
    // always
})

::: tip Spring MVC
스프링 컨트롤러에서 @RequestMapping과 함께 @RequestBody로 요청 페이로드를 Jackson ObjectMapper를 통해 JSON으로 받을 수 있다.
:::

x-www-form-urlencoded

위에서 일반적으로 서버로 요청할 때는 x-www-form-urlencoded를 Content-Type 헤더로 명시하여 전송한다고 말했다.

그러면 x-www-form-urlencoded를 Content-Type으로 사용할 경우 요청 페이로드는 어떻게 구성되는지 살펴보자.

다음은 모질라 웹 레퍼런스 문서에서 제공하는 예시이다.

POST / HTTP/1.1
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13

say=Hi&to=Mom

say=Hi&to=Mom가 위 요청에 대한 페이로드 부분이다.

이 페이로드는 키와 값을 =와 함께 표현하고 &의 묶음으로 표현하는게 x-www-form-urlencoded의 데이터 구조이다.

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

const data = {
    key1: 'foo',
    key2: 'bar'
}

axios({
    method: 'post',
    url: 'https://localhost:8080',
    data: data
}).then((res) => {
    // handle success
}).catch((err) => {
    // handle error
}).then(() => {
    // always
})

스프링 MVC에서의 모델 바인딩

사실 이 글을 쓰는 이유는 초보 개발자 입장에서 스프링 MVC에서 HTTP 요청 데이터에 대하여 어떻게 모델로 바인딩을 하는지 알려주기 위해서이다.

스프링 공식 레퍼런스 : Setting and Getting Basic and Nested Properties에서는 프로퍼티를 가져오거나 설정하는 것을 getPropertyValue와 getPropertyValues 그리고 setPropertyValue와 setPropertyValues 메소드로 수행한다고 설명한다.

그리고 자바빈 스펙에 따라 오브젝트의 프로퍼티로 나타내는 규칙도 같이 알려주고 있다.

프로퍼티 예시

  • name
    Indicates the property name that corresponds to the getName() or isName() and setName(…) methods.
  • account.name
    Indicates the nested property name of the property account that corresponds to (for example) the getAccount().setName() or getAccount().getName() methods.
  • account[2]
    Indicates the third element of the indexed property account. Indexed properties can be of type array, list, or other naturally ordered collection.
  • account[COMPANYNAME]
    Indicates the value of the map entry indexed by the COMPANYNAME key of the account Map property.

간단하게 살펴보면 account 클래스의 name 프로퍼티를 바인딩할 경우에는 account.name이라고 표현되어야하고 account[2]라고 표현되면 3번째 인덱스 프로퍼티로 나타내며 account[COMPANYNAME]이면 COMPANYNAME을 키로 가지는 Map 프로퍼티인 것이다.

@ModelAttribute

 @ModelAttribute 어노테이션은 컨트롤러에서 리퀘스트 파라미터를 쉽게 빈 오브젝트로 바인딩하기 위해 사용한다.

그런데 다음과 같이 빈 오브젝트에 맵 프로퍼티가 존재할 경우 @ModelAttribute로 데이터 바인딩을 시도할 때 주의해야한다. 앞서 x-www-form-urlencoded의 데이터 구조를 살펴본 것은 바로 이 때문이다.

만약에 빈 오브젝트에 메타데이터로 맵 오브젝트를 담고 싶다고 가정할 때 서버로 맵 오브젝트를 보내어야하는 요구사항이 생긴다.

public class Person {
    private String name;
    private Map metadata;
}

그런데 위 자바 빈 스펙 규칙에 따르면 맵 프로퍼티는 metadata[address][location]와 같이 표현되어야 한다.

그런데 서버로 요청되는 페이로드가 metadata[address][location]=value가 되어버리면 metadata 프로퍼티의 address가 배열의 인덱스인지 맵의 인덱스 키인지 구별할 수 없다

결국 관련 포스트처럼 다음과 같은 오류가 발생할 것이다.

Property referenced in indexed property path 'metadata[address][location]' is neither an array nor a List nor a Map

그러면 요청 페이로드가 .형식으로 데이터를 변환되어 metadata.address.location=value로 전송된다면 올바르게 바인딩 할 수 있을까?

답은 아니다!

바인딩이 되지 않는다.

맵 프로퍼티로 바인딩하기 위해서는 person.metadata[address]이어야만 하기 때문이다.

복잡한 페이로드라면 application/json을 사용하자.

따라서, 복잡한 형태로 데이터가 구성되어야 한다면x-www-form-urlencoded가 아니라 application/json으로 명시하여 서버가 처리할 수 있도록 해야하는게 좋다.

그리고 서버 API도 복잡한 형태의 오브젝트를 페이로드로 받도록 요구된다면 애초에 application/json만 요청할 수 있도록 하자.

{"metadata":{"address":{"location":"value"}}}

물론 스프링이 BeanWrapper 또는 DataBinder를 구현하는 것도 하나의 방법이긴 하다.

하지만, 모델 바인딩을 위한 코드를 API와 오브젝트별로 작성해야 하기에 배보다 배꼽이 더 커질수가 있다.

그리고 @Valid와 @Validated를 이용한 벨리데이션을 쉽게 적용할 수 없고 Validator도 추가로 직접 호출해서 오브젝트를 검증해야 한다.

참조

출처 : kdevkr.github.io/archives/2018/understanding-http-content-types/

 

반응형

'개발 > Note' 카테고리의 다른 글

Base64 encode / decode in C++  (0) 2020.05.29
iPhone SDK location on hard drive  (0) 2020.05.29
HMAC SHA256  (0) 2020.05.28
gdb 사용  (0) 2020.05.19
gdb 설치  (0) 2020.05.19
블로그 이미지

SKY STORY

,
반응형

KISA의 암호알고리즘을 이용한 Swift 프로젝트 셈플 입니다.

실제 프로젝트 사용 시 예제 (2/2)를 참고하세요.

 

SEED 블록암호 알고리즘 

seed.kisa.or.kr/kisa/Board/17/detailView.do

 

KISA 암호이용활성화 - 암호알고리즘 소스코드

한국인터넷진흥원(KISA)에서는 128비트 블록암호 SEED를 쉽게 활용할 수 있도록, ECB, CBC, CTR, CCM, GCM, CMAC 운영모드에 대한 소스코드를 배포하고 있습니다. 언어 : C/C++, Java, ASP, JSP, PHP  다음글 2019-01-3

seed.kisa.or.kr

 

KISA_SEED_CBC.h

다음 함수를 헤더에 선언해 주도록 한다.

extern int encryptSeedCBC( IN BYTE *pbszPlainText, OUT BYTE *pbszCipherText );
extern int decryptSeedCBC( IN BYTE *pbszCipherText, OUT BYTE *pbszPlainText );

 

KISA_SEED_CBC.c

아래 함수를 선언해 준다. 

void main(void) 함수는 제거한다.

// 초기화 벡터 - 사용자가 지정하는 초기화 벡터(16 BYTE)
BYTE pbszIV[16] = {0x026, 0x08d, 0x066, 0x0a7, 0x035, 0x0a8, 0x01a, 0x081, 0x06f, 0x0ba, 0x0d9, 0x0fa, 0x036, 0x016, 0x025, 0x001};

// 사용자가 지정하는 입력 키(16bytes), 암호화 대칭키
BYTE pbszUserKey[16] = {0x088, 0x0e3, 0x04f, 0x08f, 0x008, 0x017, 0x079, 0x0f1, 0x0e9, 0x0f3, 0x094, 0x037, 0x00a, 0x0d4, 0x005, 0x089};


int encryptSeedCBC( IN BYTE *pbszPlainText, OUT BYTE *pbszCipherText )
{
    printf("\n---------------------------------");
    printf("\nplainText : %s\n", (char *)pbszPlainText);
    
    int nPlainTextLen = (int)strlen((char *)pbszPlainText);// 평문의 Byte길이
    printf ("\n---------------------------------");
    printf ("\nSEED CBC Encryption....\n");
    // 암호문의 Byte길이 - 패딩 로직때문에 16바이트 블럭으로 처리함으로 pbszCipherText는 평문보다 16바이트 커야 한다.
    int nCipherTextLen = SEED_CBC_Encrypt( pbszUserKey, pbszIV, pbszPlainText, nPlainTextLen, pbszCipherText );
    return nCipherTextLen;
}

int decryptSeedCBC( IN BYTE *pbszCipherText, OUT BYTE *pbszPlainText )
{
    int nCipherTextLen = (int)strlen((char *)pbszCipherText);// 암호문의 Byte길이
    printf ("\n---------------------------------");
    printf ("\nSEED CBC Decryption....\n");
    // 평문의 Byte길이
    int nPlainTextLen = SEED_CBC_Decrypt( pbszUserKey, pbszIV, pbszCipherText, nCipherTextLen, pbszPlainText );
    return nPlainTextLen;
}

 

Swift에서 사용하기 위해 KISA_SEED_CBC.h, KISA_SEED_CBC.c 파일들을 프로젝트에 추가한다.

SEED.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface SEED : NSObject

+(NSString *)encrypt:(NSString *)plainText;
+(NSString *)decrypt:(NSString *)cipherText;

@end

NS_ASSUME_NONNULL_END

 

SEED.mm

#import "SEED.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "KISA_SEED_CBC.h"


@implementation SEED

+(NSString *)encrypt:(NSString *)plainText {

    BYTE pbszPlainText[2048] = {0,};
    memset(pbszPlainText, 0, [plainText length]);
    const char *byteBuff = [msg UTF8String];
    memcpy(pbszPlainText, (BYTE *)byteBuff, strlen(byteBuff));
    
    // 암호문 출력 버퍼
    BYTE pbszCipherText[2048] = {0,};
    int nCipherTextLen = encryptSeedCBC( pbszPlainText, pbszCipherText );
    
    // base64 encode
    NSData *data = [[NSData alloc] initWithBytes:pbszCipherText length:nCipherTextLen];
    NSString *base64String = [data base64EncodedStringWithOptions:0];
    
    // memory clean
    memset(pbszPlainText, 0, nCipherTextLen);
    memset((void *)[data bytes], 0, [data length]);
    
    // log
    [SEED printHexaLog:pbszCipherText length:nCipherTextLen];

    return base64String;
}

+(NSString *)decrypt:(NSString *)cipherText {

    // base64 decode
    NSData *data = [[NSData alloc] initWithBase64EncodedString:cipherText options:0];

    BYTE pbszCipherText[2048] = {0,};
    memcpy(pbszCipherText, [data bytes], [data length]);
    
    // 사용자 입력 평문
    BYTE pbszPlainText[2048] = {0,};
    int nPlainTextLen = decryptSeedCBC( pbszCipherText, pbszPlainText );
    
    NSString *plainText = [[NSString alloc] initWithBytes:pbszPlainText length:nPlainTextLen encoding:NSUTF8StringEncoding];
    
    // memory clean
    memset(pbszCipherText, 0, nPlainTextLen);
    
    // log
    [SEED printHexaLog:pbszPlainText length:nPlainTextLen];
    
    return plainText;
}

+(void)printHexaLog:(BYTE *)pbBytes length:(NSInteger)length {
    printf ("\nLength (%ld)  : ", (long)length);
    for (int i=0;i<length;i++) {
        printf("%02X ",pbBytes[i]);
    }
}

@end

 

Swift 프로젝트에 추가하고 Bridging Header 생성

#import "SEED.h"

 

사용방법 :

let str = "hello world"
let enc = SEED.encrypt(str)
print("\nenc = \(enc)")
let dec = SEED.decrypt(enc)
print("\ndec = \(dec)")

 

결과 :

---------------------------------
plainText : hello world

---------------------------------
SEED CBC Encryption....

Length (16)  : 53 81 F3 E0 18 41 85 70 29 3F 98 8F 9A A1 84 06 
enc = U4Hz4BhBhXApP5iPmqGEBg==

---------------------------------
SEED CBC Decryption....

Length (11)  : 68 65 6C 6C 6F 20 77 6F 72 6C 64 
dec = hello world

 

2020/07/11 - [분류 전체보기] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제2

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

2020/05/19 - [iOS/Tips] - Bitbucket Carthage 사용

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (3/3) - 메모리 덤프

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (2/3) - Mac OS X 환경 구축

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (1/3) - iOS디바이스 환경 구축

2020/05/19 - [iOS/Jailbreak] - Fridump, Tcpdump, OpenSSL Quick Guide

2020/05/19 - [OS/Mac OS X] - gdb 사용

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형

'개발 > iOS' 카테고리의 다른 글

Merge two different images in swift  (0) 2020.05.29
NSString <-> CBUUID 변환  (0) 2020.05.29
Array <-> Data 변환  (0) 2020.05.26
UserAgent 변경/추가  (0) 2020.05.25
RSA 암호화 / 복호화  (0) 2020.05.25
블로그 이미지

SKY STORY

,