Mega Code Archive

 
Categories / Java / Data Type
 

Hex encoderdecoder implementation borrowed from BouncyCastle

/*  * Copyright 2007 Werner Guttmann  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  * http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ import java.io.IOException; import java.io.OutputStream; import java.io.ByteArrayOutputStream; /**  * Hex encoder/decoder implementation (borrowed from BouncyCastle=.  *   * @author Johan Lindquist  * @since 1.1.1  * @version $Revision$  */ public final class HexDecoder {          /**      * Identifies the data type supported by this decoder.      */     public static final String DATA_TYPE = "hexBinary";     /**      * Initial size of the decoding table.      */     private static final int DECODING_TABLE_SIZE = 128;     /**      * Encoding table.      */     protected static final byte[] ENCODING_TABLE = {         (byte) '0', (byte) '1', (byte) '2', (byte) '3',         (byte) '4', (byte) '5', (byte) '6', (byte) '7',         (byte) '8', (byte) '9', (byte) 'A', (byte) 'B',         (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F'      };     /**      * Decoding table.      */     protected static final byte[] DECODING_TABLE = new byte[DECODING_TABLE_SIZE];     /**      * Initialize the decoding table.      */     protected static void initialiseDecodingTable() {         for (int i = 0; i < ENCODING_TABLE.length; i++) {             DECODING_TABLE[ENCODING_TABLE[i]] = (byte) i;         }         // deal with lower case letters as well         DECODING_TABLE['a'] = DECODING_TABLE['A'];         DECODING_TABLE['b'] = DECODING_TABLE['B'];         DECODING_TABLE['c'] = DECODING_TABLE['C'];         DECODING_TABLE['d'] = DECODING_TABLE['D'];         DECODING_TABLE['e'] = DECODING_TABLE['E'];         DECODING_TABLE['f'] = DECODING_TABLE['F'];     }     static {         initialiseDecodingTable();     }     /**      * Creates an instance of this class.       */     private HexDecoder() {         // Nothing to do ...     }     /**      * Encodes the input data producing a Hex output stream.      * @param data The input data to be HEX encoded      * @param off Initiak offset      * @param length Initial length of the input data array      * @param out The {@link OutputStream} instance holding the encoded input data.      * @return the number of bytes produced.      * @throws IOException If encoding fails.      */     public static int encode(final byte[] data, final int off, final int length,              final OutputStream out) throws IOException {         for (int i = off; i < (off + length); i++) {             int v = data[i] & 0xff;             out.write(ENCODING_TABLE[(v >>> 4)]);             out.write(ENCODING_TABLE[v & 0xf]);         }         return length * 2;     }     /**      * Indicates whether a given character should be ignored during en-/decoding.      * @param c The character at question.      * @return True if the given character should be ignored.      */     private static boolean ignore(final char c) {         return (c == '\n' || c == '\r' || c == '\t' || c == ' ');     }     /**      * Decodes the Hex encoded byte data writing it to the given output stream,      * whitespace characters will be ignored.      * @param data The data to be encoded      * @param off Initial offset.      * @param length Initial length      * @param out The {@link OutputStream} instance      * @return the number of bytes produced.      * @throws IOException If encoding failed.      */     public static int decode(final byte[] data, final int off, final int length,             final OutputStream out) throws IOException {         byte b1, b2;         int outLen = 0;         int end = off + length;         while (end > off) {             if (!ignore((char) data[end - 1])) {                 break;             }             end--;         }         int i = off;         while (i < end) {             while (i < end && ignore((char) data[i])) {                 i++;             }             b1 = DECODING_TABLE[data[i++]];             while (i < end && ignore((char) data[i])) {                 i++;             }             b2 = DECODING_TABLE[data[i++]];             out.write((b1 << 4) | b2);             outLen++;         }         return outLen;     }     /**      * Decodes the Hex encoded String data writing it to the given output stream,      * whitespace characters will be ignored.      *       * @param data The data to be encoded      * @param out The {@link OutputStream} instance      * @return the number of bytes produced.      * @throws IOException If encoding failed.      */     public static int decode(final String data, final OutputStream out) throws IOException {         byte b1, b2;         int length = 0;         int end = data.length();         while (end > 0) {             if (!ignore(data.charAt(end - 1))) {                 break;             }             end--;         }         int i = 0;         while (i < end) {             while (i < end && ignore(data.charAt(i))) {                 i++;             }             b1 = DECODING_TABLE[data.charAt(i++)];             while (i < end && ignore(data.charAt(i))) {                 i++;             }             b2 = DECODING_TABLE[data.charAt(i++)];             out.write((b1 << 4) | b2);             length++;         }         return length;     }     /**      * Encodes the input data producing a Hex output stream.      * @param data Input data to encode.      * @return the number of bytes produced.      */     public static String encode(final byte[] data) {         try {             final ByteArrayOutputStream out = new ByteArrayOutputStream();             encode(data, 0, data.length, out);             out.close();             return new String(out.toByteArray());         } catch (IOException e) {             e.printStackTrace();             throw new RuntimeException(e.getMessage(), e);         }     }     /**      * Decodes the HEX input data producing a output stream.      * @param data Input data to be decoded.      * @return A byte array representing the decoded input data.      */     public static byte[] decode(final String data) {         try {             final ByteArrayOutputStream out = new ByteArrayOutputStream();             decode(data, out);             out.close();             return out.toByteArray();         } catch (IOException e) {             e.printStackTrace();             throw new RuntimeException(e.getMessage(), e);         }     } }