1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.util.encoders;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.ByteArrayOutputStream;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException;
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.OutputStream;
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
7a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstromimport org.bouncycastle.util.Strings;
8a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class Hex
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private static final Encoder encoder = new HexEncoder();
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
13a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    public static String toHexString(
14a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        byte[] data)
15a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    {
16a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        return toHexString(data, 0, data.length);
17a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    }
18a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom
19a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    public static String toHexString(
20a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        byte[] data,
21a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        int    off,
22a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        int    length)
23a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    {
24a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        byte[] encoded = encode(data, off, length);
25a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        return Strings.fromByteArray(encoded);
26a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    }
27a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * encode the input data producing a Hex encoded byte array.
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a byte array containing the Hex encoded data.
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static byte[] encode(
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]    data)
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return encode(data, 0, data.length);
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * encode the input data producing a Hex encoded byte array.
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a byte array containing the Hex encoded data.
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static byte[] encode(
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]    data,
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int       off,
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int       length)
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ByteArrayOutputStream    bOut = new ByteArrayOutputStream();
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            encoder.encode(data, off, length, bOut);
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
55e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom        catch (Exception e)
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
57e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom            throw new EncoderException("exception encoding Hex string: " + e.getMessage(), e);
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return bOut.toByteArray();
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Hex encode the byte data writing it to the given output stream.
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the number of bytes produced.
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static int encode(
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]         data,
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        OutputStream   out)
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return encoder.encode(data, 0, data.length, out);
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Hex encode the byte data writing it to the given output stream.
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the number of bytes produced.
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static int encode(
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]         data,
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int            off,
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int            length,
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        OutputStream   out)
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return encoder.encode(data, off, length, out);
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * decode the Hex encoded input data. It is assumed the input data is valid.
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a byte array representing the decoded data.
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static byte[] decode(
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]    data)
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ByteArrayOutputStream    bOut = new ByteArrayOutputStream();
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            encoder.decode(data, 0, data.length, bOut);
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
105e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom        catch (Exception e)
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
107e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom            throw new DecoderException("exception decoding Hex data: " + e.getMessage(), e);
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return bOut.toByteArray();
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * decode the Hex encoded String data - whitespace will be ignored.
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a byte array representing the decoded data.
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static byte[] decode(
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String    data)
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ByteArrayOutputStream    bOut = new ByteArrayOutputStream();
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            encoder.decode(data, bOut);
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
127e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom        catch (Exception e)
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
129e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom            throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return bOut.toByteArray();
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * decode the Hex encoded String data writing it to the given output stream,
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * whitespace characters will be ignored.
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the number of bytes produced.
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static int decode(
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String          data,
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        OutputStream    out)
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return encoder.decode(data, out);
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
149