001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jose.util;
019
020import net.jcip.annotations.Immutable;
021
022import java.io.Serializable;
023import java.math.BigInteger;
024import java.util.Objects;
025
026/**
027 * Base64-encoded object.
028 *
029 * @author Vladimir Dzhuvinov
030 * @version 2024-04-20
031 */
032@Immutable
033public class Base64 implements Serializable {
034
035        private static final long serialVersionUID = 1L;
036
037        /**
038         * The Base64 value.
039         */
040        private final String value;
041
042        /**
043         * Creates a new Base64-encoded object.
044         *
045         * @param base64 The Base64-encoded object value. The value is not validated for
046         *               having characters from a Base64 alphabet. Must not be
047         *               {@code null}.
048         */
049        public Base64(final String base64) {
050
051                value = Objects.requireNonNull(base64);
052        }
053
054        /**
055         * Decodes this Base64 object to a byte array.
056         *
057         * @return The resulting byte array.
058         */
059        public byte[] decode() {
060
061                return Base64Codec.decode(value);
062        }
063
064        /**
065         * Decodes this Base64 object to an unsigned big integer.
066         *
067         * <p>
068         * Same as {@code new BigInteger(1, base64.decode())}.
069         *
070         * @return The resulting big integer.
071         */
072        public BigInteger decodeToBigInteger() {
073
074                return new BigInteger(1, decode());
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(), StandardCharset.UTF_8);
085        }
086
087        /**
088         * Returns a JSON string representation of this object.
089         *
090         * @return The JSON string representation of this object.
091         */
092        public String toJSONString() {
093                return JSONStringUtils.toJSONString(value);
094        }
095
096        /**
097         * Returns a Base64 string representation of this object. The string will be
098         * chunked into 76 character blocks separated by CRLF.
099         *
100         * @return The Base64 string representation, chunked into 76 character blocks
101         *         separated by CRLF.
102         */
103        @Override
104        public String toString() {
105
106                return value;
107        }
108
109        /**
110         * Overrides {@code Object.hashCode()}.
111         *
112         * @return The object hash code.
113         */
114        @Override
115        public int hashCode() {
116
117                return value.hashCode();
118        }
119
120        /**
121         * Overrides {@code Object.equals()}.
122         *
123         * @param object The object to compare to.
124         *
125         * @return {@code true} if the objects have the same value, otherwise
126         *         {@code false}.
127         */
128        @Override
129        public boolean equals(final Object object) {
130
131                return object instanceof Base64 && this.toString().equals(object.toString());
132        }
133
134        /**
135         * Creates a new Base64-encoded object from the specified string.
136         *
137         * @param base64 The Base64-encoded object value, {@code null} if not specified.
138         *               The value is not validated for having characters from the
139         *               Base64 alphabet.
140         *
141         * @return The Base64-encoded object, {@code null} if not specified.
142         */
143        public static Base64 from(final String base64) {
144
145                if (base64 == null) {
146                        return null;
147                }
148
149                return new Base64(base64);
150        }
151
152        /**
153         * Base64-encodes the specified byte array.
154         *
155         * @param bytes The byte array to encode. Must not be {@code null}.
156         *
157         * @return The resulting Base64 object.
158         */
159        public static Base64 encode(final byte[] bytes) {
160
161                return new Base64(Base64Codec.encodeToString(bytes, false));
162        }
163
164        /**
165         * Base64-encodes the specified big integer, without the sign bit.
166         *
167         * @param bigInt The big integer to encode. Must not be {@code null}.
168         *
169         * @return The resulting Base64 object.
170         */
171        public static Base64 encode(final BigInteger bigInt) {
172
173                return encode(BigIntegerUtils.toBytesUnsigned(bigInt));
174        }
175
176        /**
177         * Base64-encodes the specified string.
178         *
179         * @param text The string to encode. Must be in the UTF-8 character set and not
180         *             {@code null}.
181         *
182         * @return The resulting Base64 object.
183         */
184        public static Base64 encode(final String text) {
185
186                return encode(text.getBytes(StandardCharset.UTF_8));
187        }
188}