itsm_ysm/src/main/java/nlib/cmm/qrcode/QRCodeUtil.java
2021-11-26 14:47:51 +09:00

180 lines
6.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package nlib.cmm.qrcode;
import java.awt.image.BufferedImage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import egovframework.com.utl.sim.service.EgovFileScrty;
import nlib.cmm.crypto.NlibPasswordEncoder;
import nlib.user.service.NlibLoginVO;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : QRCodeUtil.java
*
* @Description : QR 코드 생성 처리
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* --------------------------------------------------------
* ※ 참고 : 바코드 정보
* --------------------------------------------------------
* [Universal Product Code : UPC] : 1D 바코드
* - UPC-A : 12자리 (6자리 제조사ID번호 + 5자리품목번호 + 1자리 체크 숫자)
* - UPC-E : 8자리 (주로 작은 패키지용으로 사용)
*
* [European Article Number : EAN Codes]
* - EAN-13(Most commonly), EAN-8, JAN-13, ISBN
* - EAN-13 : UPC 코드와 유사, "o" + UPC-A코드
*
* [Code 128]
* - 함축 고밀도 선형 코드로, 물류/배송에서 주문/유통 목적으로 주로 사용
* - 아스키 128자 인코딩 가능
*
* [PDF417]
* - 다중 1D 바코드가 다른 1D 바코드위에 쌓여서 구성되는 선형 바코드
* - 일반적인 선형 바코드기기 사용 가능
* - 여행 승차권,ID카드,물품목록 관리용으로 사용
* - 체크숫자 대신 Reed-Solomon 오류 교정 방식 사용
*
* [QR Codes : Quick Response Code]
* - 바코드 매트릭스 즉,2D 바코드로 가장 많이 쓰여지고 있는 바코드
* - 제한된 공간에 많은 양의 정보를 담을 수 있음
*
* 라이브러리
* - Barbecue : 오픈소스 자바 라이브러리, 1D바코드, PNG/GIF/JPEG/SVG 생성 기능
* - Barcode4j : 오픈소스 라이브러리, 2D바코드 포멧 지원, DataMarix, PDF417
* - ZXing(Zebra Crossing) : 오픈소스, 자바로 구현된 멀티포멧 1D/2D바코드 이미지 처리 라이브러리, QR코드 지원하는 주 자바 라이브러리 (본시스템에서 사용하는 LIB)
* - QRGen : ZXing을 사용한 간단한 자바 QR코드 생성 API
*
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 6. 25. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 6. 25.
* @version 1.0
*
*/
@Service("qrCodeService")
public class QRCodeUtil {
private static final Logger log = LoggerFactory.getLogger(QRCodeUtil.class);
/**
* QR코드로 생성할 수 있는 최대문자열 바이트 길이
*
* QR코드로 생성할 수 있는 코드값은 다음과 같으나, 본 시스템 용도에 충분한 크기인 "2000"자로 크기를 제한한다.
*
* - Numeric only Max. 7,089 characters (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
* - Alphanumeric Max. 4,296 characters (09, AZ [upper-case only], space, $, %, *, +, -, ., /, :)
* - Binary/byte Max. 2,953 characters (8-bit bytes) (23624 bits)
*/
public static final int MAX_QRTEXT_BYTES = 2000;
/**
* 입력된 문자열에 대한 QR 2D 바코드를 BufferedImage 로 생성하여 리턴한다.
*
*
* @param barcodeText
* @return
* @throws Exception
*/
public static BufferedImage generateQRCodeImageByZxing(String barcodeText) throws Exception {
if(StringUtil.isEmpty(barcodeText)) {
throw new Exception("QR 2D바코드로 생성할 문자 정보가 없습니다.");
}
if(barcodeText.getBytes().length > MAX_QRTEXT_BYTES) {
throw new Exception(String.format("QR 2D바코드로 생성할 문자의 길이는 %d 바이트를 초과할 수 없습니다.", MAX_QRTEXT_BYTES));
}
QRCodeWriter barcodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = barcodeWriter.encode(barcodeText, BarcodeFormat.QR_CODE, 200, 200);
return MatrixToImageWriter.toBufferedImage(bitMatrix);
}
/**
* 사용자정보를 가지고, QRCode 바코드를 BufferedImage 로 생성하여 리턴한다.
*
* (1) "사용자고유번호;이메일;이름;" 형식으로 문자열을 구성
* (2) 앞의 (1)의 문자열을 암호화 처리
* (3) 앞의 (2) 암호화 문자열로 QRCode 생성하여 BufferedImage형식으로 리턴
*
* @param loginVO
* @return
* @throws Exception
*/
public static BufferedImage generateMemberQrcodeImage(NlibLoginVO loginVO) throws Exception {
if(loginVO == null) {
throw new Exception("QR 2D바코드로 생성할 사용자 정보가 없습니다.");
}
if(StringUtil.isEmpty(loginVO.getMbInfoId())) {
throw new Exception("QR 2D바코드로 생성에 필요한 사용자고유번호 정보가 없습니다.");
}
if(StringUtil.isEmpty(loginVO.getEmail())) {
throw new Exception("QR 2D바코드로 생성에 필요한 이메일 정보가 없습니다.");
}
if(StringUtil.isEmpty(loginVO.getName())) {
throw new Exception("QR 2D바코드로 생성에 필요한 이름 정보가 없습니다.");
}
String barcodeText = loginVO.getMbInfoId();
return generateQRCodeImageByZxing(barcodeText);
}
/**
* 사용자 QR코드 추출 정보를 통해 사용자정보VO를 생성하여 리턴한다.
*
* @param encodedBarcodeText
* @return
* @throws Exception
*/
public static NlibLoginVO getMemberInfoFromQRCode(String encodedBarcodeText) throws Exception {
if(StringUtil.isEmpty(encodedBarcodeText)) {
throw new Exception("사용자 QR코드 추출 정보가 정보가 없습니다.");
}
log.debug("getMemberInfoFromQRCode : encodedBarcodeText=" + encodedBarcodeText);
String barcodeText = new String(EgovFileScrty.decodeBinary(encodedBarcodeText));
log.debug("getMemberInfoFromQRCode : decodedBarcodeText=" + barcodeText);
String[] split = barcodeText.split(";");
if(split.length < 3) {
throw new Exception("사용자 QR코드 추출 정보가 적합하지 않습니다.");
}
NlibLoginVO info = new NlibLoginVO();
info.setMbInfoId(split[0]);
info.setEmail(split[1]);
info.setName(split[2]);
return info;
}
}