1 | package com.jsql.util.bruter; | |
2 | ||
3 | import org.apache.commons.lang3.StringUtils; | |
4 | ||
5 | import java.nio.charset.StandardCharsets; | |
6 | import java.util.Arrays; | |
7 | ||
8 | public class Base58 { | |
9 | ||
10 | private static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray(); | |
11 | private static final int BASE_58 = Base58.ALPHABET.length; | |
12 | private static final int BASE_256 = 256; | |
13 | ||
14 | private static final int[] INDEXES = new int[128]; | |
15 | | |
16 | static { | |
17 | Arrays.fill(Base58.INDEXES, -1); | |
18 | for (int i = 0; i < Base58.ALPHABET.length; i++) { | |
19 | Base58.INDEXES[Base58.ALPHABET[i]] = i; | |
20 | } | |
21 | } | |
22 | ||
23 | private Base58() { | |
24 | // Utility class | |
25 | } | |
26 | ||
27 | public static String encode(byte[] input) { | |
28 |
1
1. encode : negated conditional → KILLED |
if (input.length == 0) { |
29 | // paying with the same coin | |
30 | return StringUtils.EMPTY; | |
31 | } | |
32 | // Make a copy of the input since we are going to modify it. | |
33 | byte[] copyInput = Base58.copyOfRange(input, 0, input.length); | |
34 | // Count leading zeroes | |
35 | var zeroCount = 0; | |
36 |
3
1. encode : negated conditional → SURVIVED 2. encode : changed conditional boundary → SURVIVED 3. encode : negated conditional → KILLED |
while (zeroCount < copyInput.length && copyInput[zeroCount] == 0) { |
37 | ++zeroCount; | |
38 | } | |
39 | // The actual encoding | |
40 |
1
1. encode : Replaced integer multiplication with division → KILLED |
var temp = new byte[copyInput.length * 2]; |
41 | int j = temp.length; | |
42 | int startAt = zeroCount; | |
43 |
2
1. encode : negated conditional → KILLED 2. encode : changed conditional boundary → KILLED |
while (startAt < copyInput.length) { |
44 | byte mod = Base58.divmod58(copyInput, startAt); | |
45 |
1
1. encode : negated conditional → KILLED |
if (copyInput[startAt] == 0) { |
46 |
1
1. encode : Changed increment from 1 to -1 → KILLED |
++startAt; |
47 | } | |
48 |
1
1. encode : Changed increment from -1 to 1 → KILLED |
temp[--j] = (byte) Base58.ALPHABET[mod]; |
49 | } | |
50 | // Strip extra '1' if any | |
51 |
3
1. encode : changed conditional boundary → SURVIVED 2. encode : negated conditional → SURVIVED 3. encode : negated conditional → KILLED |
while (j < temp.length && temp[j] == Base58.ALPHABET[0]) { |
52 | ++j; | |
53 | } | |
54 | // Add as many leading '1' as there were leading zeros. | |
55 |
3
1. encode : changed conditional boundary → SURVIVED 2. encode : Changed increment from -1 to 1 → KILLED 3. encode : negated conditional → KILLED |
while (--zeroCount >= 0) { |
56 |
1
1. encode : Changed increment from -1 to 1 → NO_COVERAGE |
temp[--j] = (byte) Base58.ALPHABET[0]; |
57 | } | |
58 | byte[] output = Base58.copyOfRange(temp, j, temp.length); | |
59 |
1
1. encode : replaced return value with "" for com/jsql/util/bruter/Base58::encode → KILLED |
return new String(output, StandardCharsets.UTF_8); |
60 | } | |
61 | ||
62 | public static byte[] decode(String input) { | |
63 |
1
1. decode : negated conditional → KILLED |
if (input.isEmpty()) { |
64 | // paying with the same coin | |
65 |
1
1. decode : replaced return value with null for com/jsql/util/bruter/Base58::decode → NO_COVERAGE |
return new byte[0]; |
66 | } | |
67 | var input58 = new byte[input.length()]; | |
68 | // Transform the String to a base58 byte sequence | |
69 |
2
1. decode : changed conditional boundary → KILLED 2. decode : negated conditional → KILLED |
for (var i = 0; i < input.length(); ++i) { |
70 | var c = input.charAt(i); | |
71 | int digit58 = -1; | |
72 |
4
1. decode : changed conditional boundary → SURVIVED 2. decode : changed conditional boundary → SURVIVED 3. decode : negated conditional → KILLED 4. decode : negated conditional → KILLED |
if (c >= 0 && c < 128) { |
73 | digit58 = Base58.INDEXES[c]; | |
74 | } | |
75 |
2
1. decode : negated conditional → KILLED 2. decode : changed conditional boundary → KILLED |
if (digit58 < 0) { |
76 | throw new IllegalArgumentException("Not a Base58 input: " + input); | |
77 | } | |
78 | input58[i] = (byte) digit58; | |
79 | } | |
80 | ||
81 | // Count leading zeroes | |
82 | var zeroCount = 0; | |
83 |
3
1. decode : negated conditional → SURVIVED 2. decode : changed conditional boundary → SURVIVED 3. decode : negated conditional → KILLED |
while (zeroCount < input58.length && input58[zeroCount] == 0) { |
84 | ++zeroCount; | |
85 | } | |
86 | ||
87 | // The encoding | |
88 | var temp = new byte[input.length()]; | |
89 | int j = temp.length; | |
90 | ||
91 | int startAt = zeroCount; | |
92 |
2
1. decode : changed conditional boundary → KILLED 2. decode : negated conditional → KILLED |
while (startAt < input58.length) { |
93 | byte mod = Base58.divmod256(input58, startAt); | |
94 |
1
1. decode : negated conditional → KILLED |
if (input58[startAt] == 0) { |
95 |
1
1. decode : Changed increment from 1 to -1 → KILLED |
++startAt; |
96 | } | |
97 |
1
1. decode : Changed increment from -1 to 1 → KILLED |
temp[--j] = mod; |
98 | } | |
99 | // Do no add extra leading zeroes, move j to first non-null byte. | |
100 |
3
1. decode : changed conditional boundary → SURVIVED 2. decode : negated conditional → KILLED 3. decode : negated conditional → KILLED |
while (j < temp.length && temp[j] == 0) { |
101 | ++j; | |
102 | } | |
103 |
2
1. decode : Replaced integer subtraction with addition → SURVIVED 2. decode : replaced return value with null for com/jsql/util/bruter/Base58::decode → KILLED |
return Base58.copyOfRange(temp, j - zeroCount, temp.length); |
104 | } | |
105 | ||
106 | private static byte divmod58(byte[] number, int startAt) { | |
107 | var remainder = 0; | |
108 |
2
1. divmod58 : changed conditional boundary → KILLED 2. divmod58 : negated conditional → KILLED |
for (int i = startAt; i < number.length; i++) { |
109 |
1
1. divmod58 : Replaced bitwise AND with OR → KILLED |
int digit256 = number[i] & 0xFF; |
110 |
2
1. divmod58 : Replaced integer multiplication with division → KILLED 2. divmod58 : Replaced integer addition with subtraction → KILLED |
int temp = remainder * Base58.BASE_256 + digit256; |
111 |
1
1. divmod58 : Replaced integer division with multiplication → KILLED |
number[i] = (byte) (temp / Base58.BASE_58); |
112 |
1
1. divmod58 : Replaced integer modulus with multiplication → KILLED |
remainder = temp % Base58.BASE_58; |
113 | } | |
114 |
1
1. divmod58 : replaced byte return with 0 for com/jsql/util/bruter/Base58::divmod58 → KILLED |
return (byte) remainder; |
115 | } | |
116 | ||
117 | private static byte divmod256(byte[] number58, int startAt) { | |
118 | var remainder = 0; | |
119 |
2
1. divmod256 : negated conditional → KILLED 2. divmod256 : changed conditional boundary → KILLED |
for (int i = startAt; i < number58.length; i++) { |
120 |
1
1. divmod256 : Replaced bitwise AND with OR → KILLED |
int digit58 = number58[i] & 0xFF; |
121 |
2
1. divmod256 : Replaced integer multiplication with division → KILLED 2. divmod256 : Replaced integer addition with subtraction → KILLED |
int temp = remainder * Base58.BASE_58 + digit58; |
122 |
1
1. divmod256 : Replaced integer division with multiplication → KILLED |
number58[i] = (byte) (temp / Base58.BASE_256); |
123 |
1
1. divmod256 : Replaced integer modulus with multiplication → KILLED |
remainder = temp % Base58.BASE_256; |
124 | } | |
125 |
1
1. divmod256 : replaced byte return with 0 for com/jsql/util/bruter/Base58::divmod256 → KILLED |
return (byte) remainder; |
126 | } | |
127 | ||
128 | private static byte[] copyOfRange(byte[] source, int from, int to) { | |
129 |
1
1. copyOfRange : Replaced integer subtraction with addition → KILLED |
var range = new byte[to - from]; |
130 |
1
1. copyOfRange : removed call to java/lang/System::arraycopy → KILLED |
System.arraycopy(source, from, range, 0, range.length); |
131 |
1
1. copyOfRange : replaced return value with null for com/jsql/util/bruter/Base58::copyOfRange → KILLED |
return range; |
132 | } | |
133 | } | |
Mutations | ||
28 |
1.1 |
|
36 |
1.1 2.2 3.3 |
|
40 |
1.1 |
|
43 |
1.1 2.2 |
|
45 |
1.1 |
|
46 |
1.1 |
|
48 |
1.1 |
|
51 |
1.1 2.2 3.3 |
|
55 |
1.1 2.2 3.3 |
|
56 |
1.1 |
|
59 |
1.1 |
|
63 |
1.1 |
|
65 |
1.1 |
|
69 |
1.1 2.2 |
|
72 |
1.1 2.2 3.3 4.4 |
|
75 |
1.1 2.2 |
|
83 |
1.1 2.2 3.3 |
|
92 |
1.1 2.2 |
|
94 |
1.1 |
|
95 |
1.1 |
|
97 |
1.1 |
|
100 |
1.1 2.2 3.3 |
|
103 |
1.1 2.2 |
|
108 |
1.1 2.2 |
|
109 |
1.1 |
|
110 |
1.1 2.2 |
|
111 |
1.1 |
|
112 |
1.1 |
|
114 |
1.1 |
|
119 |
1.1 2.2 |
|
120 |
1.1 |
|
121 |
1.1 2.2 |
|
122 |
1.1 |
|
123 |
1.1 |
|
125 |
1.1 |
|
129 |
1.1 |
|
130 |
1.1 |
|
131 |
1.1 |