22
33
44import java .io .ByteArrayOutputStream ;
5+ import java .util .Arrays ;
56
67/**
78 * A Base62 encoder/decoder.
@@ -46,15 +47,38 @@ public static Base62 createInstanceWithInvertedCharacterSet() {
4647 return new Base62 (CharacterSets .INVERTED );
4748 }
4849
50+ /**
51+ * Encodes a sequence of bytes in Base62 encoding and pads it accordingly.
52+ *
53+ * @param message a byte sequence.
54+ * @param length the expected length.
55+ * @return a sequence of Base62-encoded bytes.
56+ */
57+ public byte [] encode (byte [] message , int length ) {
58+ byte [] indices = convert (message , STANDARD_BASE , TARGET_BASE , length );
59+ return translate (indices , alphabet );
60+ }
61+
4962 /**
5063 * Encodes a sequence of bytes in Base62 encoding.
5164 *
5265 * @param message a byte sequence.
5366 * @return a sequence of Base62-encoded bytes.
5467 */
5568 public byte [] encode (byte [] message ) {
56- byte [] indices = convert (message , STANDARD_BASE , TARGET_BASE );
57- return translate (indices , alphabet );
69+ return encode (message , -1 );
70+ }
71+
72+ /**
73+ * Decodes a sequence of Base62-encoded bytes and pads it accordingly.
74+ *
75+ * @param encoded a sequence of Base62-encoded bytes.
76+ * @param length the expected length.
77+ * @return a byte sequence.
78+ */
79+ public byte [] decode (byte [] encoded , int length ) {
80+ byte [] prepared = translate (encoded , lookup );
81+ return convert (prepared , TARGET_BASE , STANDARD_BASE , length );
5882 }
5983
6084 /**
@@ -64,8 +88,7 @@ public byte[] encode(byte[] message) {
6488 * @return a byte sequence.
6589 */
6690 public byte [] decode (byte [] encoded ) {
67- byte [] prepared = translate (encoded , lookup );
68- return convert (prepared , TARGET_BASE , STANDARD_BASE );
91+ return decode (encoded , -1 );
6992 }
7093
7194 /**
@@ -83,10 +106,10 @@ private byte[] translate(byte[] indices, byte[] dictionary) {
83106 /**
84107 * Converts a byte array from a source base to a target base using the alphabet.
85108 */
86- private byte [] convert (byte [] message , int sourceBase , int targetBase ) {
109+ private byte [] convert (byte [] message , int sourceBase , int targetBase , int length ) {
87110 // This algorithm is inspired by: http://codegolf.stackexchange.com/a/21672
88111
89- int estimatedLength = estimateOutputLength (message .length , sourceBase , targetBase );
112+ int estimatedLength = length == - 1 ? estimateOutputLength (message .length , sourceBase , targetBase ) : length ;
90113 ByteArrayOutputStream out = new ByteArrayOutputStream (estimatedLength );
91114 byte [] source = message ;
92115 while (source .length > 0 ) {
@@ -104,11 +127,17 @@ private byte[] convert(byte[] message, int sourceBase, int targetBase) {
104127 source = quotient .toByteArray ();
105128 }
106129
107- // pad output with zeroes corresponding to the number of leading zeroes in the message
108- for (int i = 0 ; i < estimatedLength - out .size (); i ++)
109- out .write (0 );
130+ if (out .size () < estimatedLength ) {
131+ int size = out .size ();
132+ for (int i = 0 ; i < estimatedLength - size ; i ++)
133+ out .write (0 );
110134
111- return reverse (out .toByteArray ());
135+ return reverse (out .toByteArray ());
136+ } else if (out .size () > estimatedLength ) {
137+ return reverse (Arrays .copyOfRange (out .toByteArray (), 0 , estimatedLength ));
138+ } else {
139+ return reverse (out .toByteArray ());
140+ }
112141 }
113142
114143 /**
0 commit comments