001package com.nimbusds.jose.util; 002 003 004import java.io.UnsupportedEncodingException; 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 * Base64URL-encoded object. 015 * 016 * <p>Related specifications: 017 * 018 * <ul> 019 * <li>RFC 4648. 020 * </ul> 021 * 022 * @author Vladimir Dzhuvinov 023 * @version $version$ (2013-03-20) 024 */ 025@Immutable 026public class Base64URL implements JSONAware { 027 028 029 /** 030 * The Base64URL value. 031 */ 032 private final String value; 033 034 035 /** 036 * Creates a new Base64URL-encoded object. 037 * 038 * @param base64URL The Base64URL-encoded object value. The value is 039 * not validated for having characters from the 040 * Base64URL alphabet. Must not be {@code null}. 041 */ 042 public Base64URL(final String base64URL) { 043 044 if (base64URL == null) { 045 046 throw new IllegalArgumentException("The Base64URL value must not be null"); 047 } 048 049 value = base64URL; 050 } 051 052 053 /** 054 * Decodes this Base64URL 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 Base64URL object to an unsigned big integer. 066 * 067 * <p>Same as {@code new BigInteger(1, base64url.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 Base64URL object to a string. 079 * 080 * @return The resulting string, in the UTF-8 character set. 081 */ 082 public String decodeToString() { 083 084 try { 085 return new String(decode(), Base64.CHARSET); 086 087 } catch (UnsupportedEncodingException e) { 088 089 // UTF-8 should always be supported 090 return ""; 091 } 092 } 093 094 095 /** 096 * Returns a JSON string representation of this object. 097 * 098 * @return The JSON string representation of this object. 099 */ 100 @Override 101 public String toJSONString() { 102 103 return "\"" + JSONValue.escape(value) + "\""; 104 } 105 106 107 /** 108 * Returns a Base64URL string representation of this object. 109 * 110 * @return The Base64URL string representation. 111 */ 112 @Override 113 public String toString() { 114 115 return value; 116 } 117 118 119 /** 120 * Overrides {@code Object.hashCode()}. 121 * 122 * @return The object hash code. 123 */ 124 @Override 125 public int hashCode() { 126 127 return value.hashCode(); 128 } 129 130 131 /** 132 * Overrides {@code Object.equals()}. 133 * 134 * @param object The object to compare to. 135 * 136 * @return {@code true} if the objects have the same value, otherwise 137 * {@code false}. 138 */ 139 @Override 140 public boolean equals(final Object object) { 141 142 return object != null && 143 object instanceof Base64URL && 144 this.toString().equals(object.toString()); 145 } 146 147 148 /** 149 * Base64URL-encodes the specified byte array. 150 * 151 * @param bytes The byte array to encode. Must not be {@code null}. 152 * 153 * @return The resulting Base64URL object. 154 */ 155 public static Base64URL encode(final byte[] bytes) { 156 157 return new Base64URL(org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(bytes)); 158 } 159 160 161 /** 162 * Base64URL-encodes the specified big integer, without the sign bit. 163 * 164 * @param bigInt The big integer to encode. Must not be {@code null}. 165 * 166 * @return The resulting Base64URL object. 167 */ 168 public static Base64URL encode(final BigInteger bigInt) { 169 170 return encode(BigIntegerUtils.toBytesUnsigned(bigInt)); 171 } 172 173 174 /** 175 * Base64URL-encodes the specified string. 176 * 177 * @param text The string to encode. Must be in the UTF-8 character set 178 * and not {@code null}. 179 * 180 * @return The resulting Base64URL object. 181 */ 182 public static Base64URL encode(final String text) { 183 184 try { 185 return encode(text.getBytes(Base64.CHARSET)); 186 187 } catch (UnsupportedEncodingException e) { 188 189 // UTF-8 should always be supported 190 return null; 191 } 192 } 193}