Base58.java

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
Location : encode
Killed by : StringUtilSpock.[engine:spock]/[spec:StringUtilSpock]/[feature:$spock_feature_0_0]
negated conditional → KILLED

36

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

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 Covering tests

40

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

43

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

45

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

46

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

48

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

51

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

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 Covering tests

55

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
Covering tests

56

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

59

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

63

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

65

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

69

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

72

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

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 Covering tests

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

75

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

83

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
Covering tests

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

92

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

94

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

95

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

97

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

100

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

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

103

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
Covering tests

108

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

109

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

110

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

111

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

112

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

114

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

119

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

120

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

121

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

122

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

123

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

125

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

129

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

130

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

131

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.19.1