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