001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.coder; 020 021import lucee.commons.io.CharsetUtil; 022 023 024/** 025 * 026 */ 027public final class HexCoder { 028 029 /** 030 * encodes a byte array to a String 031 * @param bytes 032 * @return encoed String 033 */ 034 public static String encode(byte[] bytes) { 035 String retorno = ""; 036 if (bytes==null || bytes.length==0) { 037 return retorno; 038 } 039 for (int i=0; i<bytes.length; i++) { 040 byte valor = bytes[i]; 041 int d1 = valor & 0xF; 042 d1 += (d1 < 10) ? 48 : 55; 043 int d2 = (valor & 0xF0) >> 4; 044 d2 += (d2 < 10) ? 48 : 55; 045 retorno = retorno + (char)d2 + (char)d1; 046 } 047 return retorno; 048 } 049 050 /** 051 * decodes back a String to a byte array 052 * @param hexa 053 * @return decoded byte array 054 * @throws CoderException 055 */ 056 public static byte[] decode(String hexa) throws CoderException { 057 if (hexa == null) { 058 throw new CoderException("can't decode empty String"); 059 } 060 if ((hexa.length() % 2) != 0) { 061 throw new CoderException("invalid hexadicimal String"); 062 } 063 int tamArray = hexa.length() / 2; 064 byte[] retorno = new byte[tamArray]; 065 for (int i=0; i<tamArray; i++) { 066 retorno[i] = hexToByte(hexa.substring(i*2,i*2+2)); 067 } 068 return retorno; 069 } 070 071 private static byte hexToByte(String hexa) throws CoderException { 072 if (hexa == null) { 073 throw new CoderException("can't decode empty String"); 074 } 075 if (hexa.length() != 2) { 076 throw new CoderException("invalid hexadicimal String"); 077 } 078 byte[] b = hexa.getBytes(CharsetUtil.UTF8); 079 byte valor = (byte) (hexDigitValue((char)b[0]) * 16 + 080 hexDigitValue((char)b[1])); 081 return valor; 082 } 083 084 private static int hexDigitValue(char c) throws CoderException { 085 int retorno = 0; 086 if (c>='0' && c<='9') { 087 retorno = (((byte)c) - 48); 088 } 089 else if (c>='A' && c<='F') { 090 retorno = (((byte)c) - 55); 091 } 092 else if (c>='a' && c<='f') { 093 retorno = (((byte)c) - 87); 094 } 095 else { 096 throw new CoderException("invalid hexadicimal String"); 097 } 098 return retorno; 099 } 100 101}