HexEncoder.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1package org.bouncycastle.util.encoders;
2
3import java.io.IOException;
4import java.io.OutputStream;
5
6public class HexEncoder
7    implements Encoder
8{
9    protected final byte[] encodingTable =
10        {
11            (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
12            (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'
13        };
14
15    /*
16     * set up the decoding table.
17     */
18    protected final byte[] decodingTable = new byte[128];
19
20    protected void initialiseDecodingTable()
21    {
22        for (int i = 0; i < encodingTable.length; i++)
23        {
24            decodingTable[encodingTable[i]] = (byte)i;
25        }
26
27        decodingTable['A'] = decodingTable['a'];
28        decodingTable['B'] = decodingTable['b'];
29        decodingTable['C'] = decodingTable['c'];
30        decodingTable['D'] = decodingTable['d'];
31        decodingTable['E'] = decodingTable['e'];
32        decodingTable['F'] = decodingTable['f'];
33    }
34
35    public HexEncoder()
36    {
37        initialiseDecodingTable();
38    }
39
40    /**
41     * encode the input data producing a Hex output stream.
42     *
43     * @return the number of bytes produced.
44     */
45    public int encode(
46        byte[]                data,
47        int                    off,
48        int                    length,
49        OutputStream    out)
50        throws IOException
51    {
52        for (int i = off; i < (off + length); i++)
53        {
54            int    v = data[i] & 0xff;
55
56            out.write(encodingTable[(v >>> 4)]);
57            out.write(encodingTable[v & 0xf]);
58        }
59
60        return length * 2;
61    }
62
63    private boolean ignore(
64        char    c)
65    {
66        return (c == '\n' || c =='\r' || c == '\t' || c == ' ');
67    }
68
69    /**
70     * decode the Hex encoded byte data writing it to the given output stream,
71     * whitespace characters will be ignored.
72     *
73     * @return the number of bytes produced.
74     */
75    public int decode(
76        byte[]          data,
77        int             off,
78        int             length,
79        OutputStream    out)
80        throws IOException
81    {
82        byte    b1, b2;
83        int     outLen = 0;
84
85        int     end = off + length;
86
87        while (end > off)
88        {
89            if (!ignore((char)data[end - 1]))
90            {
91                break;
92            }
93
94            end--;
95        }
96
97        int i = off;
98        while (i < end)
99        {
100            while (i < end && ignore((char)data[i]))
101            {
102                i++;
103            }
104
105            b1 = decodingTable[data[i++]];
106
107            while (i < end && ignore((char)data[i]))
108            {
109                i++;
110            }
111
112            b2 = decodingTable[data[i++]];
113
114            out.write((b1 << 4) | b2);
115
116            outLen++;
117        }
118
119        return outLen;
120    }
121
122    /**
123     * decode the Hex encoded String data writing it to the given output stream,
124     * whitespace characters will be ignored.
125     *
126     * @return the number of bytes produced.
127     */
128    public int decode(
129        String          data,
130        OutputStream    out)
131        throws IOException
132    {
133        byte    b1, b2;
134        int     length = 0;
135
136        int     end = data.length();
137
138        while (end > 0)
139        {
140            if (!ignore(data.charAt(end - 1)))
141            {
142                break;
143            }
144
145            end--;
146        }
147
148        int i = 0;
149        while (i < end)
150        {
151            while (i < end && ignore(data.charAt(i)))
152            {
153                i++;
154            }
155
156            b1 = decodingTable[data.charAt(i++)];
157
158            while (i < end && ignore(data.charAt(i)))
159            {
160                i++;
161            }
162
163            b2 = decodingTable[data.charAt(i++)];
164
165            out.write((b1 << 4) | b2);
166
167            length++;
168        }
169
170        return length;
171    }
172}
173