본문 바로가기
JSP

[ JSP ] Base64인코딩,디코딩

by 정윤재 2008. 10. 20.

웹에서 데이터를 전달(Content-Transfer)하기 위한 목적으로 사용됩니다. 사람이 읽을 수 없는 (바이너리)데이터의 경우 내용과 형태가 멋대로인 경우가 많아서 이 상태 그대로는 HTTP프로토콜을 이용해서 전달하기가 애매모호한데, 이것을 일관성 있는 데이터로 바꿔줍니다. base64인코딩을 할경우 US-ASCII에서 이용하는 65개의 pritable 문자로 데이터를 재구성합니다.

===>이 얘기를 달리 말하면 한글이나 특수 문자와 같은 2byte 이상의 문자가 영문자로 바뀌어서 넘어가기 때문에 깨지지 않는다고 생각하시면 됩니다. 넘겨야 할 변수가 많다면 귀찮아서 문제가 되겠지만 일을 하다보면 이렇게 일일히 해줘야 할 때도 분명히 있습니다.(톰캣 5.x대 버전 부터  filter가 지원되지만 다른 환경일 때가 많죠)

어찌 됐든 제가 완성 시킨 코드를 첨부합니다.

Base64Test.jsp -> Base64View.jsp -> Base64DAO.java
Base64Test.jsp에서 자바 스크립트로 인코딩해서 submit() 시킨 것을 Base64View.jsp에서 받아서 Base64DAO.java가 디코딩 해 주는 로직입니다.

Base64Test.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
http://www.w3.org/TR/html4/loose.dtd">
<html>
<HEAD>
<script>
function deco(form){

  var InStr = form.ar1.value;
  var len_1 = InStr.length;
  var ttb = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  var len_res = InStr.length % 4;
  var len_div = len_1 - len_res;
  var re = new makeArray(3);
  var In  = new makeArray(4);
  var DecNum = new makeArray(4);
  var i=0;
  var Stat = "";
  var tmp16, tmp16s;
  var EnB=4;
  var str="";

  while(1)
  {
    if( i >= len_1 )
         break;

    for(k=1;k<=4;k++)
    {
      In[k] = InStr.charAt(i++);
      DecNum[k] = ttb.indexOf(In[k]);
    }

    if( i >= len_div )
    {
        Stat = "End"; 
        if( len_res == 3 || DecNum[4] == 64 )
          EnB = 3;
        if( len_res == 2 || DecNum[3] == 64 )
          EnB = 2;
    }

    re[1] = ( DecNum[1] << 2 ) + ( DecNum[2] >> 4);
    re[2] = ( ( DecNum[2] & 15 ) << 4 ) + ( DecNum[3] >> 2);
    re[3] = ( ( DecNum[3] & 3 ) << 6 ) | DecNum[4] ;

    for(k=1;k<=3;k++)
    {
       if( k < EnB )
       {
          tmp16 = re[k].toString(16);
          tmp16s = "%" + tmp16;
          str = str + tmp16s  ;
       }
    }
   }
  str = unescape(str);
  form.ar1.value = str;
 
}

function enco(form){
//base64 인코딩 함수 (자바스크립트에서 인코딩 해서 넘김)

  var InStr = form.ar1.value;
  var ttb = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  var len_1 = InStr.length;
  var len_res = InStr.length % 3;
  var len_div = len_1 - len_res;
  var ra = new makeArray(4);
  var i=0;
  var Stat = "";

  var str="";
  while(1)
  {
    if( i >= len_1 )
         break;


    if( i >= len_div )
         Stat = "End"; 

    A = eval(InStr.charCodeAt(i++));
    B = eval(InStr.charCodeAt(i++));
    C = eval(InStr.charCodeAt(i++));

    if( i > len_div )
    {
        Stat = "End"; 

        if( len_res >= 1)
          C = 0;
        if( len_res == 1 )
          B = 0;
    }
    ra[1] = A >> 2;
    ra[2] = ( (A & 3) << 4 ) + (B >> 4);
    ra[3] = ( ( B & 15 ) << 2 ) + ( C >> 6);
    ra[4] = C & 63;

    if( Stat == "End" && len_res >= 1 )
          ra[4] = 64;
    if( Stat == "End" && len_res == 1 )
          ra[3] = 64;

    for(k=1;k<=4;k++)
       str = str + ttb.substr(ra[k],1);
 } 
 form.ar1.value = str;
 alert(str);
 form.action="base64View.jsp";
 form.submit();
}

function makeArray(n){
    this.length=n
    for(var i=1; i<=n; i++){
            this[i]=null;
    }
    return this
}
</script></Head>

 

<BODY BGCOLOR=gainsboro text=black>
Base 64 인코딩 자바 스크립트
<form method="post">
<TEXTAREA NAME="ar1"' rows=10 cols=60></TEXTAREA><br>
<INPUT TYPE="button" name="df" VALUE="인코딩" onClick='enco(this.form)'>
<INPUT TYPE="button" name="df" VALUE="디코딩" onClick='deco(this.form)'>
<!-- Base64Test.jsp에서 바로 디코딩하는 모습도 볼 수 있습니다. -->
</FORM>


</BODY>


</html>



/////////////////////////////////////////////////////////////////
Base64View.jsp

<%@ page language="java" import="l1j.server.Base64,l1j.server.L1DatabaseFactory,com.*"contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
http://www.w3.org/TR/html4/loose.dtd">
<%

String df=request.getParameter("ar1");
System.out.println("넘어온 값===>"+df);
df=new String(df.getBytes("8859_1"),"UTF-8");
System.out.println("스트링 변환===>"+df);
Base64DAO decode= new Base64DAO();    
 
df=decode.decode(df);
//Base64DAO에서 디코딩 해 줍니다.

%>


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>
<body>
<%=df%>
</body>
</html>
///////////////////////////////////////////////////////////////
Base64DAO.java

package com;

//Base64Decoder.java
//$Id: Base64Decoder.java,v 1.3 1999/02/19 16:14:33 ylafon Exp $
//(c) COPYRIGHT MIT and INRIA, 1996.
//Please first read the full copyright statement in file COPYRIGHT.html

//package org.w3c.tools.codec ;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import sun.misc.*;
 

public class Base64DAO{
  
 public static String decode(String strDecode) {
    byte[] buf = null;
    String rtn="";
    BASE64Decoder base64Decoder = new BASE64Decoder();
    ByteArrayInputStream bin = new ByteArrayInputStream(strDecode.getBytes());
    ByteArrayOutputStream bout = new ByteArrayOutputStream();

    try {
     base64Decoder.decodeBuffer(bin, bout);
     // 다행히도 JAVA에는 Base64를 디코딩해주는 메소드가 존재하는군요
    // try catch는 필수 입니다.
    } catch (Exception e) {
     System.out.println("Exception");
     e.printStackTrace();
    }
    buf = bout.toByteArray();
    rtn = new String(buf);
    return rtn;
  }
}



 


댓글