blob: 54567cf09f367f9ff036c6e899e4748cd7524e72 [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2
3package org.xbill.DNS.utils;
4
5import java.io.*;
6
7/**
8 * Routines for converting between Strings of base64-encoded data and arrays of
9 * binary data.
10 *
11 * @author Brian Wellington
12 */
13
14public class base64 {
15
16private static final String Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
17
18private
19base64() {}
20
21/**
22 * Convert binary data to a base64-encoded String
23 * @param b An array containing binary data
24 * @return A String containing the encoded data
25 */
26public static String
27toString(byte [] b) {
28 ByteArrayOutputStream os = new ByteArrayOutputStream();
29
30 for (int i = 0; i < (b.length + 2) / 3; i++) {
31 short [] s = new short[3];
32 short [] t = new short[4];
33 for (int j = 0; j < 3; j++) {
34 if ((i * 3 + j) < b.length)
35 s[j] = (short) (b[i*3+j] & 0xFF);
36 else
37 s[j] = -1;
38 }
39
40 t[0] = (short) (s[0] >> 2);
41 if (s[1] == -1)
42 t[1] = (short) (((s[0] & 0x3) << 4));
43 else
44 t[1] = (short) (((s[0] & 0x3) << 4) + (s[1] >> 4));
45 if (s[1] == -1)
46 t[2] = t[3] = 64;
47 else if (s[2] == -1) {
48 t[2] = (short) (((s[1] & 0xF) << 2));
49 t[3] = 64;
50 }
51 else {
52 t[2] = (short) (((s[1] & 0xF) << 2) + (s[2] >> 6));
53 t[3] = (short) (s[2] & 0x3F);
54 }
55 for (int j = 0; j < 4; j++)
56 os.write(Base64.charAt(t[j]));
57 }
58 return new String(os.toByteArray());
59}
60
61/**
62 * Formats data into a nicely formatted base64 encoded String
63 * @param b An array containing binary data
64 * @param lineLength The number of characters per line
65 * @param prefix A string prefixing the characters on each line
66 * @param addClose Whether to add a close parenthesis or not
67 * @return A String representing the formatted output
68 */
69public static String
70formatString(byte [] b, int lineLength, String prefix, boolean addClose) {
71 String s = toString(b);
72 StringBuffer sb = new StringBuffer();
73 for (int i = 0; i < s.length(); i += lineLength) {
74 sb.append (prefix);
75 if (i + lineLength >= s.length()) {
76 sb.append(s.substring(i));
77 if (addClose)
78 sb.append(" )");
79 }
80 else {
81 sb.append(s.substring(i, i + lineLength));
82 sb.append("\n");
83 }
84 }
85 return sb.toString();
86}
87
88
89/**
90 * Convert a base64-encoded String to binary data
91 * @param str A String containing the encoded data
92 * @return An array containing the binary data, or null if the string is invalid
93 */
94public static byte []
95fromString(String str) {
96 ByteArrayOutputStream bs = new ByteArrayOutputStream();
97 byte [] raw = str.getBytes();
98 for (int i = 0; i < raw.length; i++) {
99 if (!Character.isWhitespace((char)raw[i]))
100 bs.write(raw[i]);
101 }
102 byte [] in = bs.toByteArray();
103 if (in.length % 4 != 0) {
104 return null;
105 }
106
107 bs.reset();
108 DataOutputStream ds = new DataOutputStream(bs);
109
110 for (int i = 0; i < (in.length + 3) / 4; i++) {
111 short [] s = new short[4];
112 short [] t = new short[3];
113
114 for (int j = 0; j < 4; j++)
115 s[j] = (short) Base64.indexOf(in[i*4+j]);
116
117 t[0] = (short) ((s[0] << 2) + (s[1] >> 4));
118 if (s[2] == 64) {
119 t[1] = t[2] = (short) (-1);
120 if ((s[1] & 0xF) != 0)
121 return null;
122 }
123 else if (s[3] == 64) {
124 t[1] = (short) (((s[1] << 4) + (s[2] >> 2)) & 0xFF);
125 t[2] = (short) (-1);
126 if ((s[2] & 0x3) != 0)
127 return null;
128 }
129 else {
130 t[1] = (short) (((s[1] << 4) + (s[2] >> 2)) & 0xFF);
131 t[2] = (short) (((s[2] << 6) + s[3]) & 0xFF);
132 }
133
134 try {
135 for (int j = 0; j < 3; j++)
136 if (t[j] >= 0)
137 ds.writeByte(t[j]);
138 }
139 catch (IOException e) {
140 }
141 }
142 return bs.toByteArray();
143}
144
145}