001    package railo.runtime.coder;
002    
003    
004    /**
005     * 
006     */
007    public final class HexCoder {
008            
009            /**
010             * encodes a byte array to a String
011             * @param bytes
012             * @return encoed String
013             */
014            public static String encode(byte[] bytes) {
015                    String retorno = "";
016                    if (bytes==null || bytes.length==0) {
017                            return retorno;
018                    }
019                    for (int i=0; i<bytes.length; i++) {
020                            byte valor = bytes[i];
021                            int d1 = valor & 0xF;
022                            d1 += (d1 < 10) ? 48 : 55;
023                            int d2 = (valor & 0xF0) >> 4;
024                            d2 += (d2 < 10) ? 48 : 55;
025                            retorno = retorno + (char)d2 + (char)d1;
026                    }
027                    return retorno;
028            }
029    
030            /**
031             * decodes back a String to a byte array
032             * @param hexa
033             * @return decoded byte array
034             * @throws CoderException
035             */
036            public static byte[] decode(String hexa) throws CoderException {
037                    if (hexa == null) {
038                            throw new CoderException("can't decode empty String");
039                    }
040                    if ((hexa.length() % 2) != 0) {
041                            throw new CoderException("invalid hexadicimal String");
042                    }
043                    int tamArray = hexa.length() / 2;
044                    byte[] retorno = new byte[tamArray];
045                    for (int i=0; i<tamArray; i++) {
046                            retorno[i] = hexToByte(hexa.substring(i*2,i*2+2));
047                    }
048                    return retorno;
049            }
050    
051            private static byte hexToByte(String hexa) throws CoderException {
052                    if (hexa == null) {
053                            throw new CoderException("can't decode empty String");
054                    }
055                    if (hexa.length() != 2) {
056                            throw new CoderException("invalid hexadicimal String");
057                    }
058                    byte[] b = hexa.getBytes();
059                    byte valor = (byte) (hexDigitValue((char)b[0]) * 16 +
060                                                                    hexDigitValue((char)b[1]));
061                    return valor;
062            }
063    
064            private static int hexDigitValue(char c) throws CoderException {
065                    int retorno = 0;
066                    if (c>='0' && c<='9') {
067                            retorno = (((byte)c) - 48);
068                    }
069                    else if (c>='A' && c<='F') {
070                            retorno = (((byte)c) - 55);
071                    }
072                    else if (c>='a' && c<='f') {
073                            retorno = (((byte)c) - 87);
074                    }
075                    else {
076                            throw new CoderException("invalid hexadicimal String");
077                    }
078                    return retorno;
079            }
080            
081    }