Base58.java

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

Mutations

28

1.1
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

38

1.1
Location : encode
Killed by : none
negated conditional → SURVIVED

2.2
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

3.3
Location : encode
Killed by : none
changed conditional boundary → SURVIVED

43

1.1
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced integer multiplication with division → KILLED

47

1.1
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

2.2
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
changed conditional boundary → KILLED

50

1.1
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

51

1.1
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Changed increment from 1 to -1 → KILLED

54

1.1
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Changed increment from -1 to 1 → KILLED

58

1.1
Location : encode
Killed by : none
changed conditional boundary → SURVIVED

2.2
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

3.3
Location : encode
Killed by : none
negated conditional → SURVIVED

63

1.1
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Changed increment from -1 to 1 → KILLED

2.2
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

3.3
Location : encode
Killed by : none
changed conditional boundary → SURVIVED

64

1.1
Location : encode
Killed by : none
Changed increment from -1 to 1 → NO_COVERAGE

69

1.1
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
replaced return value with "" for com/jsql/util/bruter/Base58::encode → KILLED

74

1.1
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

76

1.1
Location : decode
Killed by : none
replaced return value with null for com/jsql/util/bruter/Base58::decode → NO_COVERAGE

82

1.1
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
changed conditional boundary → KILLED

2.2
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

87

1.1
Location : decode
Killed by : none
changed conditional boundary → SURVIVED

2.2
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

3.3
Location : decode
Killed by : none
changed conditional boundary → SURVIVED

4.4
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

91

1.1
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

2.2
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
changed conditional boundary → KILLED

100

1.1
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

2.2
Location : decode
Killed by : none
negated conditional → SURVIVED

3.3
Location : decode
Killed by : none
changed conditional boundary → SURVIVED

109

1.1
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
changed conditional boundary → KILLED

2.2
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

112

1.1
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

113

1.1
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Changed increment from 1 to -1 → KILLED

116

1.1
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Changed increment from -1 to 1 → KILLED

120

1.1
Location : decode
Killed by : none
changed conditional boundary → SURVIVED

2.2
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

3.3
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

124

1.1
Location : decode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
replaced return value with null for com/jsql/util/bruter/Base58::decode → KILLED

2.2
Location : decode
Killed by : none
Replaced integer subtraction with addition → SURVIVED

130

1.1
Location : divmod58
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
changed conditional boundary → KILLED

2.2
Location : divmod58
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

132

1.1
Location : divmod58
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced bitwise AND with OR → KILLED

133

1.1
Location : divmod58
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced integer multiplication with division → KILLED

2.2
Location : divmod58
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced integer addition with subtraction → KILLED

135

1.1
Location : divmod58
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced integer division with multiplication → KILLED

137

1.1
Location : divmod58
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced integer modulus with multiplication → KILLED

140

1.1
Location : divmod58
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
replaced byte return with 0 for com/jsql/util/bruter/Base58::divmod58 → KILLED

146

1.1
Location : divmod256
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

2.2
Location : divmod256
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
changed conditional boundary → KILLED

148

1.1
Location : divmod256
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced bitwise AND with OR → KILLED

149

1.1
Location : divmod256
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced integer multiplication with division → KILLED

2.2
Location : divmod256
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced integer addition with subtraction → KILLED

151

1.1
Location : divmod256
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced integer division with multiplication → KILLED

153

1.1
Location : divmod256
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced integer modulus with multiplication → KILLED

156

1.1
Location : divmod256
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
replaced byte return with 0 for com/jsql/util/bruter/Base58::divmod256 → KILLED

161

1.1
Location : copyOfRange
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
Replaced integer subtraction with addition → KILLED

162

1.1
Location : copyOfRange
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
removed call to java/lang/System::arraycopy → KILLED

164

1.1
Location : copyOfRange
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
replaced return value with null for com/jsql/util/bruter/Base58::copyOfRange → KILLED

Active mutators

Tests examined


Report generated by PIT 1.16.1