Programing/JAVA

ASN.1 구조체 생성 및 인코딩 방법

리커니 2019. 3. 18.
반응형

ASN.1 구조체 생성 및 인코딩 방법

 

우선 ASN.1 구조체를 만들기 위해서는 .asn 확장자의 전문과

그 전문이 어떤구조인지 파악 할 수 있는 인터페이스 정의서가 필요합니다.
어떤 구조인지 알아야 원하는 값을 넣을 수 있겠죠?

.asn 확장자의 전문이 만들어지면 OSS라는 프로그램으로 java 프로젝트를 생성할 수 있고,
그 프로젝트를 이클립스와 같은 IDE에서 jar 파일로 추출 할 수 있습니다.

추출된 jar 파일을 ASN.1 을 사용할 프로젝트에 추가하여야
전문과 같은 추상 구조체를 생성할 수 있습니다.

OSS 프로그램을 사용하여 jar 파일을 만드는 방법은 아래의 Link를 참고하세요.

 

Link : ASN.1 Java jar 파일 만드는 방법 How to make ASN.1 jar file

 

ASN.1 Java jar 파일 만드는 방법 How to make ASN.1 jar file

ASN.1 Java jar 파일 만드는 방법 How to make ASN.1 jar file ASN.1 은 특정 장치, 데이터 표현방식, 프로그래밍 언어 등에 종속되지 않도록 표준화된 OSI 계층모델의 표현계층 상에서 쓰이는 추상 구조체를

aljjabaegi.tistory.com

 

그럼 생성된 jar 파일을 프로젝트에 추가하고 ASN.1 구조체를 만드는 방법에 대해서 알아보도록 하겠습니다.
우선 OSS 프로그램으로 Export된 프로젝트를 IDE에 Import한 것을 보면 구조를 파악하는데 도움이됩니다.
프로젝트 내 전문 java 파일의 생성자를 참고하시면 됩니다.

그런데 처음에 해깔리는 부분이 java 개발을 하면서 볼 수 없었던 타입들이 있는 부분인데요
예를들면, UTF8String16, GeneralizedTime, Enumerated 와 같은 클래스를 상속받은 클래스 들입니다.
보시면 대충 감은 오실꺼에요. 구조체를 만들어 보면서 자세히 알아보도록 하죠.

OSS 프로그램을 통해 만들어진 자바 프로젝트를 IDE에 Import해 보시면
src 내에 java 클래스를 확인 할 수 있습니다.

ASN1Project 를 상속받은 클래스가 아닌 Sequence 등을 상속받은 java 파일을 보시면
(예를들어 그 파일이 AccidentInformation.java 파일이라면)
아래와 같은 생성자를 보실 수 있습니다. 예를들어 아래와 같다고 하죠.

public AccidentInformation(){}

public AccidentInformation(UTF8String16 accidentNumber, PrintableString callNumber
AccidentType accidentType, VehicleType vehicleType, INTEGER vehicleDirection){
    setAccidentNumber(accidentNumber);
    setCallNumber(callNumber)
    setAccidentType(accidentType);
    setVehicleType(vehicleType);
    setVehicleDirectionIvehicleDirection);
}

 

 

아래의 생성자를 보시면 어떤 구조로 되어있는지 파악이 가능합니다.
UTF8String16, PrintableString, INTEGER의 경우 대충 String과 Integer 타입일꺼 같은 느낌이옵니다. 맞습니다.
그럼 나머지들은 뭘까요?
해당 클래스를 확인하시면 각각의 타입을 상속받는것을 보실 수 있습니다.

 

public static class AccidentType extends BitString {...}
public static final class VehicleType extends Enumerated {...}

 

이제 각각의 타입에 맞게 set을 해보도록 하죠.
클래스를 인스턴스화 합니다.

 

AccidentInformation ai = new AccidentInformation();

 

내부 값들에 대해서는 set 메소드를 제공하니 호출해서 타입에 맞게 값을 넣으시면 됩니다.
(set할 값 들은 vo객체로 받는다는 가정)

 

ai.setAccidentNumber(new UTF8String16(vo.getAccidentNumber()));
ai.setCallNumber(new PrintableString(vo.getCallNumber()));
ai.setVehicleDirection(vo.getVehicleDirection());

 

그럼 BitString과 Enumerated를 상속받은 클래스는 어떻게 할까요?
BitString을 먼저 보도록 하죠.
해당 클래스로 이동합니다. 그럼 이름이 정의된 상수들을 보실 수 있습니다.

 

public static final int vehicleAndVehicle = 0;
public static final int vehicleAndHuman = 1;
public static final int vehicleAlong = 2;
public static final int multiCrash = 3;

 

값을 확인하고 해당 클래스를 인스턴스화 해서 원하는 값을 넣어 set하시면 됩니다. (복수 가능)

 

AccidentType at = new AccidentType();
at.setBit(0); //vehicleAndVehicle
at.setBit(1); //vehicleAndHuman
ai.setAccidentType(at);

 

Enumberated 도 비슷합니다. 클래스를 확인하면 아래와 같은 내부 클래스를 확인하실 수 있습니다.

 

public static final class Value {
    public static final long passengerLight = 0;
    public static final long passengerSmall = 1;
    public static final long passengerMedium = 2;
    public static final long passengerLarge = 3;
}

 

passengerLight 을 set 하고 싶다면

 

ai.setVehicleType(Vehicletype.passengerLight);


하시면 됩니다.

다른 타입들도 위와 같이 타입에 맞게 set 해주시면 됩니다.


이제 ASN.1구조체에 데이터가 set 되었으니 인코딩 하는 방법을 알아보도록 하겠습니다.
인코딩을 하기 위해서는 Coder와 ByteArrayOutputStream, ASN.1추상객체(구조체)가 필요합니다.

구조체는 위에서 생성을 했고
Coder같은 경우 인코딩 룰에 맞게 생성을 합니다.

PER의 경우

 

Coder coder = Trafficaccidentoccurrenceinformation.getPERUnalignedCoder();

 

아웃풋스트림도 인스턴스화 하고

 

ByteArrayOutputStream baos = new ByteArrayOutputStream();

 

인코딩을 하시면 됩니다.

 

try {
    coder.encode(ai, baos);
} catch (EncodeFailedException | EncodeNotSupportedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

 

그럼 ASN.1 구조체가 ByteArrayOutputStream 에 들어가게 됩니다.
이제 이 ByteArrayOutputStream을 byte배열로 변환하시거나(.toByteArray() 사용)
통신 방식에 맞게 변환하여 전송하시면 됩니다.

다음 포스팅에서는 ASN.1 디코딩 방식에 대해서 알아보도록 하겠습니다.

 

반응형

댓글

💲 추천 글