1 package org.bouncycastle.util.encoders; 2 3 import java.io.IOException; 4 import java.io.OutputStream; 5 6 public 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 initialiseDecodingTable()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 HexEncoder()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 */ encode( byte[] data, int off, int length, OutputStream out)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 ignore( char c)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 */ decode( byte[] data, int off, int length, OutputStream out)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 */ decode( String data, OutputStream out)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