byte[] mutate(final byte[] buf) {
    byte[] res = buf.clone();
    int nm = 1 + this.exp2();
    for (int i = 0; i < nm; i++) {
      int x = this.rand(16);
      if (x == 0) {
        // Remove a range of bytes.
        if (res.length <= 1) {
          i--;
          continue;
        }
        int pos0 = this.rand(res.length);
        int pos1 = pos0 + this.chooseLen(res.length - pos0);
        copy(res, pos1, res, pos0, res.length - pos0);
        res = Arrays.copyOfRange(res, 0, res.length - (pos1 - pos0));
      } else if (x == 1) {
        // Insert a range of random bytes.
        int pos = this.rand(res.length + 1);
        int n = this.chooseLen(10);
        res = concatZeros(res, n);
        copy(res, pos, res, pos + n);
        for (int k = 0; k < n; k++) {
          res[pos + k] = (byte) this.rand(256);
        }
      } else if (x == 2) {
        // Duplicate a range of bytes.
        if (res.length <= 1) {
          i--;
          continue;
        }
        int src = this.rand(res.length);
        int dst = this.rand(res.length);
        while (src == dst) {
          dst = this.rand(res.length);
        }
        int n = this.chooseLen(res.length - src);
        byte[] tmp = new byte[n];
        Arrays.fill(tmp, (byte) 0);
        copy(res, src, tmp, 0);
        res = concatZeros(res, n);
        copy(res, dst, res, dst + n);
        System.arraycopy(tmp, 0, res, dst, n);
      } else if (x == 3) {
        // Copy a range of bytes.
        if (res.length <= 1) {
          i--;
          continue;
        }
        int src = this.rand(res.length);
        int dst = this.rand(res.length);
        while (src == dst) {
          dst = this.rand(res.length);
        }
        int n = this.chooseLen(res.length - src);
        copy(res, src + n, res, dst);
      } else if (x == 4) {
        // Bit flip. Spooky!
        if (res.length <= 1) {
          i--;
          continue;
        }
        int pos = this.rand(res.length);
        res[pos] ^= (byte) (1 << (byte) this.rand(8));
      } else if (x == 5) {
        // Set a byte to a random value.
        if (res.length <= 1) {
          i--;
          continue;
        }
        int pos = this.rand(res.length);
        res[pos] ^= (byte) (this.rand(255) + 1);
      } else if (x == 6) {
        // Swap 2 bytes.
        if (res.length <= 1) {
          i--;
          continue;
        }
        int src = this.rand(res.length);
        int dst = this.rand(res.length);
        while (src == dst) {
          dst = this.rand(res.length);
        }
        byte tmp1 = res[src];
        res[src] = res[dst];
        res[dst] = tmp1;
      } else if (x == 7) {
        // Add/subtract from a byte.
        if (res.length == 0) {
          i--;
          continue;
        }
        int pos = this.rand(res.length);
        int v = this.rand(35) + 1;
        if (this.randBool()) {
          res[pos] += (byte) v;
        } else {
          res[pos] -= (byte) v;
        }
      } else if (x == 8) {
        // Add/subtract from a uint16.
        i--;
        //                if (res.length < 2) {
        //                    i--;
        //                    continue;
        //                }
        //                int pos = this.rand(res.length - 1);
        //                int v = this.rand(35) + 1;
        //                if (this.randBool()) {
        //                    v = 0 - v;
        //                }
        //
        //                if (this.randBool()) {
        //                    res[pos] =
        //                } else {
        //
        //                }

      } else if (x == 9) {
        i--;
        // Add/subtract from a uint32.
      } else if (x == 10) {
        // Replace a byte with an interesting value.
        if (res.length == 0) {
          i--;
          continue;
        }
        int pos = this.rand(res.length);
        res[pos] = (byte) INTERESTING8[this.rand(INTERESTING8.length)];
      } else if (x == 11) {
        // Replace an uint16 with an interesting value.
        if (res.length < 2) {
          i--;
          continue;
        }
        int pos = this.rand(res.length - 1);
        if (this.randBool()) {
          res[pos] = (byte) (INTERESTING16[this.rand(INTERESTING16.length)] & 0xFF);
          res[pos + 1] = (byte) ((INTERESTING16[this.rand(INTERESTING16.length)] >> 8) & 0xFF);
        } else {
          res[pos + 1] = (byte) (INTERESTING16[this.rand(INTERESTING16.length)] & 0xFF);
          res[pos] = (byte) ((INTERESTING16[this.rand(INTERESTING16.length)] >> 8) & 0xFF);
        }
      } else if (x == 12) {
        // Replace an uint32 with an interesting value.
        if (res.length < 4) {
          i--;
          continue;
        }
        int pos = this.rand(res.length - 3);
        if (this.randBool()) {
          res[pos] = (byte) (INTERESTING32[this.rand(INTERESTING32.length)] & 0xFF);
          res[pos + 1] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 8) & 0xFF);
          res[pos + 2] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 16) & 0xFF);
          res[pos + 3] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 24) & 0xFF);
        } else {
          res[pos + 3] = (byte) (INTERESTING32[this.rand(INTERESTING32.length)] & 0xFF);
          res[pos + 2] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 8) & 0xFF);
          res[pos + 1] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 16) & 0xFF);
          res[pos] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 24) & 0xFF);
        }
      } else if (x == 13) {
        // Replace an ascii digit with another digit.
        List<Integer> digits = new ArrayList<>();
        for (int k = 0; k < res.length; k++) {
          if (res[k] >= 48 && res[k] <= 57) {
            digits.add(k);
          }
        }
        if (digits.isEmpty()) {
          i--;
          continue;
        }
        int pos = this.rand(digits.size());
        int was = res[digits.get(pos)];
        int now = was;
        while (now == was) {
          now = this.rand(10) + 48;
        }
        res[digits.get(pos)] = (byte) now;
      } else if (x == 14) {
        // Splice another input.
        if (res.length < 4 || this.inputs.size() < 2) {
          i--;
          continue;
        }
        byte[] other = this.inputs.get(this.rand(this.inputs.size()));
        if (other.length < 4) {
          i--;
          continue;
        }
        // Find common prefix and suffix.
        int idx0 = 0;
        while (idx0 < res.length && idx0 < other.length && res[idx0] == other[idx0]) {
          idx0++;
        }
        int idx1 = 0;
        while (idx1 < res.length
            && idx1 < other.length
            && res[res.length - idx1 - 1] == other[other.length - idx1 - 1]) {
          idx1++;
        }
        int diff = Math.min(res.length - idx0 - idx1, other.length - idx0 - idx1);
        if (diff < 4) {
          i--;
          continue;
        }
        copy(other, idx0, res, idx0, Math.min(other.length, idx0 + this.rand(diff - 2) + 1) - idx0);
      } else if (x == 15) {
        // Insert a part of another input.
        if (res.length < 4 || this.inputs.size() < 2) {
          i--;
          continue;
        }
        byte[] other = this.inputs.get(this.rand(this.inputs.size()));
        if (other.length < 4) {
          i--;
          continue;
        }
        int pos0 = this.rand(res.length + 1);
        int pos1 = this.rand(other.length - 2);
        int n = this.chooseLen(other.length - pos1 - 2) + 2;
        res = concatZeros(res, n);
        copy(res, pos0, res, pos0 + n);
        if (n >= 0) System.arraycopy(other, pos1, res, pos0, n);
      }
    }

    if (res.length > this.maxInputSize) {
      res = Arrays.copyOfRange(res, 0, this.maxInputSize);
    }
    return res;
  }
Create a corpus

@param dirs The directory to store the corpus files
testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/Corpus.java