View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.codec.binary;
19  
20  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  
26  import java.math.BigInteger;
27  
28  import org.apache.commons.lang3.ArrayUtils;
29  import org.junit.jupiter.api.Test;
30  
31  /**
32   * Tests {@link BaseNCodec#toUnsignedBytes(BigInteger)}.
33   */
34  class BaseNCodecToIntegerBytesTest {
35  
36      @Test
37      void testBigIntegerWithAllZeros() {
38          final BigInteger allZeros = new BigInteger("0");
39          final byte[] result = BaseNCodec.toUnsignedBytes(allZeros);
40          assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, result);
41      }
42  
43      @Test
44      void testBigIntegerWithBoundaryValues() {
45          // Test boundary values that might cause overflow or underflow issues
46          final BigInteger[] boundaries = { BigInteger.valueOf(Integer.MAX_VALUE), BigInteger.valueOf(Integer.MIN_VALUE), BigInteger.valueOf(Long.MAX_VALUE),
47                  BigInteger.valueOf(Long.MIN_VALUE) };
48          for (final BigInteger boundary : boundaries) {
49              assertNotNull(BaseNCodec.toUnsignedBytes(boundary), "Should handle boundary value: " + boundary);
50          }
51      }
52  
53      @Test
54      void testBigIntegerWithByteBoundaryValues() {
55          // Test specific byte boundary values
56          final BigInteger[] boundaryValues = { BigInteger.valueOf(Byte.MAX_VALUE), // 127
57                  BigInteger.valueOf(Byte.MIN_VALUE), // -128
58                  BigInteger.valueOf(255), // 255 (unsigned byte max)
59                  BigInteger.valueOf(-256) // -256
60          };
61          for (final BigInteger boundary : boundaryValues) {
62              assertNotNull(BaseNCodec.toUnsignedBytes(boundary), "Should handle boundary value: " + boundary);
63          }
64      }
65  
66      @Test
67      void testBigIntegerWithDecimalString() {
68          final BigInteger decimal = new BigInteger("100");
69          final byte[] result = BaseNCodec.toUnsignedBytes(decimal);
70          assertNotNull(result);
71          assertTrue(result.length > 0);
72      }
73  
74      @Test
75      void testBigIntegerWithHexValues() {
76          // Test with hex string representation
77          final BigInteger hexValue = new BigInteger("FF", 16); // 255
78          final byte[] result = BaseNCodec.toUnsignedBytes(hexValue);
79          assertNotNull(result);
80          assertEquals(1, result.length);
81          assertEquals(-1, result[0]); // -1 in two's complement
82      }
83  
84      @Test
85      void testBigIntegerWithLargeValues() {
86          // Test very large numbers that exceed typical integer ranges
87          final BigInteger huge = new BigInteger("9223372036854775807"); // Long.MAX_VALUE
88          final byte[] result = BaseNCodec.toUnsignedBytes(huge);
89          assertNotNull(result);
90          assertTrue(result.length > 0);
91      }
92  
93      @Test
94      void testBigIntegerWithLeadingZeros() {
95          // Create a BigInteger that would have leading zeros in byte representation
96          final BigInteger big = new BigInteger("00000000000000000000000000000001", 16);
97          final byte[] result = BaseNCodec.toUnsignedBytes(big);
98          assertNotNull(result);
99          assertEquals(1, result.length);
100         assertEquals(1, result[0]);
101     }
102 
103     @Test
104     void testBigIntegerWithMaxValue() {
105         final BigInteger max = BigInteger.valueOf(Long.MAX_VALUE);
106         final byte[] result = BaseNCodec.toUnsignedBytes(max);
107         assertNotNull(result);
108         assertTrue(result.length > 0);
109     }
110 
111     @Test
112     void testBigIntegerWithMinValue() {
113         final BigInteger min = BigInteger.valueOf(Long.MIN_VALUE);
114         final byte[] result = BaseNCodec.toUnsignedBytes(min);
115         assertNotNull(result);
116         assertTrue(result.length > 0);
117     }
118 
119     @Test
120     void testBigIntegerWithMixedSigns() {
121         // Test that the method correctly handles negative numbers
122         final BigInteger[] negativeValues = { BigInteger.valueOf(-1), BigInteger.valueOf(-256), BigInteger.valueOf(Integer.MIN_VALUE),
123                 new BigInteger("-999999999999999999") };
124         for (final BigInteger negative : negativeValues) {
125             assertNotNull(BaseNCodec.toUnsignedBytes(negative), "Should handle negative value: " + negative);
126         }
127     }
128 
129     @Test
130     void testBigIntegerWithMultipleBytes() {
131         // Test a number that requires multiple bytes to represent
132         final BigInteger multiByte = new BigInteger("65536"); // 2^16
133         final byte[] result = BaseNCodec.toUnsignedBytes(multiByte);
134         assertNotNull(result);
135         assertTrue(result.length >= 2);
136         // Should correctly represent the multi-byte value
137     }
138 
139     @Test
140     void testBigIntegerWithNegativeHexValues() {
141         // Test with negative hex values
142         final BigInteger hexNeg = new BigInteger("80", 16); // -128 in two's complement
143         final byte[] result = BaseNCodec.toUnsignedBytes(hexNeg);
144         assertNotNull(result);
145         assertEquals(1, result.length);
146         assertEquals(-128, result[0]);
147     }
148 
149     @Test
150     void testBigIntegerWithNegativeLargeValues() {
151         final BigInteger hugeNeg = new BigInteger("-9223372036854775808"); // Long.MIN_VALUE
152         final byte[] result = BaseNCodec.toUnsignedBytes(hugeNeg);
153         assertNotNull(result);
154         assertTrue(result.length > 0);
155     }
156 
157     @Test
158     void testBigIntegerWithNegativeVeryLargeNumber() {
159         final String largeString = "-1234567890123456789012345678901234567890";
160         final BigInteger large = new BigInteger(largeString);
161         final byte[] result = BaseNCodec.toUnsignedBytes(large);
162         assertNotNull(result);
163         assertTrue(result.length > 0);
164     }
165 
166     @Test
167     void testBigIntegerWithOverflowProtection() {
168         // Test that the method handles overflow conditions gracefully
169         final BigInteger overflowTest = new BigInteger("12345678901234567890123456789012345678901234567890");
170         final byte[] result = BaseNCodec.toUnsignedBytes(overflowTest);
171         assertNotNull(result);
172         assertTrue(result.length > 0);
173     }
174 
175     @Test
176     void testBigIntegerWithSingleByteRange() {
177         // Test boundary values for single byte range
178         final BigInteger[] testValues = { BigInteger.valueOf(-128), // -128 (minimum byte value)
179                 BigInteger.valueOf(-127), // -127
180                 BigInteger.valueOf(-1), // -1
181                 BigInteger.valueOf(0), // 0
182                 BigInteger.valueOf(1), // 1
183                 BigInteger.valueOf(126), // 126
184                 BigInteger.valueOf(127) // 127 (maximum byte value)
185         };
186         for (final BigInteger value : testValues) {
187             final byte[] result = BaseNCodec.toUnsignedBytes(value);
188             assertNotNull(result, "Should not return null for value: " + value);
189         }
190     }
191 
192     @Test
193     void testBigIntegerWithVeryLargeNumber() {
194         // Test with numbers that have many digits
195         final String largeString = "1234567890123456789012345678901234567890";
196         final BigInteger large = new BigInteger(largeString);
197         final byte[] result = BaseNCodec.toUnsignedBytes(large);
198         assertNotNull(result);
199         assertTrue(result.length > 0);
200     }
201 
202     @Test
203     void testBigIntegerWithVeryLargePositiveValue() {
204         final BigInteger veryLarge = new BigInteger("123456789012345678901234567890");
205         final byte[] result = BaseNCodec.toUnsignedBytes(veryLarge);
206         assertNotNull(result);
207         assertTrue(result.length > 0);
208     }
209 
210     @Test
211     void testBigIntegerWithVerySmallNegativeValue() {
212         final BigInteger verySmall = new BigInteger("-256");
213         final byte[] result = BaseNCodec.toUnsignedBytes(verySmall);
214         assertNotNull(result);
215         assertTrue(result.length > 0);
216     }
217 
218     @Test
219     void testBigIntegerWithZeroInDifferentFormats() {
220         // Different ways to represent zero
221         final BigInteger zero1 = BigInteger.ZERO;
222         final BigInteger zero2 = new BigInteger("0");
223         final BigInteger zero3 = new BigInteger("0000000000000000");
224         final byte[] result1 = BaseNCodec.toUnsignedBytes(zero1);
225         final byte[] result2 = BaseNCodec.toUnsignedBytes(zero2);
226         final byte[] result3 = BaseNCodec.toUnsignedBytes(zero3);
227         assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, result1);
228         assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, result2);
229         assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, result3);
230     }
231 
232 
233     @Test
234     void testLargeNegativeBigInteger() {
235         final BigInteger large = new BigInteger("-2147483648"); // Integer.MIN_VALUE
236         final byte[] result = BaseNCodec.toUnsignedBytes(large);
237         assertNotNull(result);
238         // Should handle large negative numbers correctly
239         assertTrue(result.length > 0);
240     }
241 
242     @Test
243     void testLargePositiveBigInteger() {
244         final BigInteger large = new BigInteger("2147483647"); // Integer.MAX_VALUE
245         final byte[] result = BaseNCodec.toUnsignedBytes(large);
246         assertNotNull(result);
247         // Should handle large positive numbers correctly
248         assertTrue(result.length > 0);
249     }
250 
251     @Test
252     void testNullBigInteger() {
253         assertThrows(NullPointerException.class, () -> {
254             BaseNCodec.toUnsignedBytes(null);
255         });
256     }
257 
258     @Test
259     void testOneBigInteger() {
260         final BigInteger one = BigInteger.ONE;
261         final byte[] result = BaseNCodec.toUnsignedBytes(one);
262         assertNotNull(result);
263         // Should represent the integer value 1
264         assertEquals(1, result.length);
265         assertEquals(1, result[0]);
266     }
267 
268     @Test
269     void testSmallNegativeBigInteger() {
270         final BigInteger small = new BigInteger("-128");
271         final byte[] result = BaseNCodec.toUnsignedBytes(small);
272         assertNotNull(result);
273         assertEquals(1, result.length);
274         assertEquals(-128, result[0]);
275     }
276 
277     @Test
278     void testSmallPositiveBigInteger() {
279         final BigInteger small = new BigInteger("127");
280         final byte[] result = BaseNCodec.toUnsignedBytes(small);
281         assertNotNull(result);
282         assertEquals(1, result.length);
283         assertEquals(127, result[0]);
284     }
285 
286 }