001package com.nimbusds.jose.util;
002
003
004import java.nio.charset.Charset;
005import java.math.BigInteger;
006
007import net.jcip.annotations.Immutable;
008
009import net.minidev.json.JSONAware;
010import net.minidev.json.JSONValue;
011
012
013/**
014 * Base64-encoded object.
015 *
016 * @author Vladimir Dzhuvinov
017 * @version $version$ (2013-05-16)
018 */
019@Immutable
020public class Base64 implements JSONAware {
021
022
023        /**
024         * UTF-8 is the required character set for all JOSE + JWT objects.
025         */
026        public static final Charset CHARSET = Charset.forName("UTF-8");
027
028
029        /**
030         * The Base64 value.
031         */
032        private final String value;
033
034
035        /**
036         * Creates a new Base64-encoded object.
037         *
038         * @param base64 The Base64-encoded object value. The value is not 
039         *               validated for having characters from a Base64 
040         *               alphabet. Must not be {@code null}.
041         */
042        public Base64(final String base64) {
043
044                if (base64 == null) {
045
046                        throw new IllegalArgumentException("The Base64 value must not be null");
047                }
048
049                value = base64;
050        }
051
052
053        /**
054         * Decodes this Base64 object to a byte array.
055         *
056         * @return The resulting byte array.
057         */
058        public byte[] decode() {
059
060                return org.apache.commons.codec.binary.Base64.decodeBase64(value);
061        }
062
063
064        /**
065         * Decodes this Base64 object to an unsigned big integer.
066         *
067         * <p>Same as {@code new BigInteger(1, base64.decode())}.
068         *
069         * @return The resulting big integer.
070         */
071        public BigInteger decodeToBigInteger() {
072
073                return new BigInteger(1, decode());
074        }
075
076
077        /**
078         * Decodes this Base64 object to a string.
079         *
080         * @return The resulting string, in the UTF-8 character set.
081         */
082        public String decodeToString() {
083
084                return new String(decode(), CHARSET);
085        }
086
087
088        /**
089         * Returns a JSON string representation of this object.
090         *
091         * @return The JSON string representation of this object.
092         */
093        @Override
094        public String toJSONString() {
095
096                return "\"" + JSONValue.escape(value) + "\"";
097        }
098
099
100        /**
101         * Returns a Base64 string representation of this object. The string 
102         * will be chunked into 76 character blocks separated by CRLF.
103         *
104         * @return The Base64 string representation, chunked into 76 character 
105         *         blocks separated by CRLF.
106         */
107        @Override
108        public String toString() {
109
110                return value;
111        }
112
113
114        /**
115         * Overrides {@code Object.hashCode()}.
116         *
117         * @return The object hash code.
118         */
119        @Override
120        public int hashCode() {
121
122                return value.hashCode();
123        }
124
125
126        /**
127         * Overrides {@code Object.equals()}.
128         *
129         * @param object The object to compare to.
130         *
131         * @return {@code true} if the objects have the same value, otherwise
132         *         {@code false}.
133         */
134        @Override
135        public boolean equals(final Object object) {
136
137                return object != null && 
138                       object instanceof Base64 && 
139                       this.toString().equals(object.toString());
140        }
141
142
143        /**
144         * Base64-encodes the specified byte array. 
145         *
146         * @param bytes The byte array to encode. Must not be {@code null}.
147         *
148         * @return The resulting Base64 object.
149         */
150        public static Base64 encode(final byte[] bytes) {
151
152                return new Base64(org.apache.commons.codec.binary.Base64.encodeBase64String(bytes));
153        }
154
155
156        /**
157         * Base64-encodes the specified big integer, without the sign bit.
158         *
159         * @param bigInt The big integer to encode. Must not be {@code null}.
160         *
161         * @return The resulting Base64 object.
162         */
163        public static Base64 encode(final BigInteger bigInt) {
164
165                return encode(BigIntegerUtils.toBytesUnsigned(bigInt));
166        }
167
168
169        /**
170         * Base64-encodes the specified string.
171         *
172         * @param text The string to encode. Must be in the UTF-8 character set
173         *             and not {@code null}.
174         *
175         * @return The resulting Base64 object.
176         */
177        public static Base64 encode(final String text) {
178
179                return encode(text.getBytes(CHARSET));
180        }
181}