private static byte[] convert(byte[] message, int sourceBase, int targetBase) {
    int estimatedLength = estimateOutputLength(message.length, sourceBase, targetBase);
    BufferExposingByteArrayOutputStream out = new BufferExposingByteArrayOutputStream(estimatedLength);
    byte[] source = message;
    while (source.length > 0) {
      BufferExposingByteArrayOutputStream quotient = new BufferExposingByteArrayOutputStream(source.length);

      int remainder = 0;

      for (byte b : source) {
        int accumulator = (b & 0xFF) + remainder * sourceBase;
        int digit = (accumulator - (accumulator % targetBase)) / targetBase;

        remainder = accumulator % targetBase;

        if (quotient.size() > 0 || digit > 0) {
          quotient.write(digit);
        }
      }

      out.write(remainder);

      source = quotient.toByteArray();
    }

    // pad output with zeroes corresponding to the number of leading zeroes in the message
    for (int i = 0; i < message.length - 1 && message[i] == 0; i++) {
      out.write(0);
    }

    int length = out.size();
    byte[] array = out.getInternalBuffer();
    int i = 0;
    int j = length - 1;
    while (j > i) {
      byte tmp = array[j];
      array[j] = array[i];
      array[i] = tmp;
      j--;
      i++;
    }
    return array;
  }
private static byte[] convert(byte[] message, int sourceBase, int targetBase)