@Override
    public byte[][] split(byte[] start, byte[] end, int numSplits, boolean inclusive) {
      BigInteger s = convertToBigInteger(start);
      BigInteger e = convertToBigInteger(end);

      Preconditions.checkArgument(e.compareTo(s) > 0,
        "last row (%s) is configured less than first row (%s)", rowToStr(end), end);
      // +1 to range because the last row is inclusive
      BigInteger range = e.subtract(s).add(BigInteger.ONE);
      Preconditions.checkState(range.compareTo(BigInteger.valueOf(numSplits)) >= 0,
        "split granularity (%s) is greater than the range (%s)", numSplits, range);

      BigInteger[] splits = new BigInteger[numSplits - 1];
      BigInteger sizeOfEachSplit = range.divide(BigInteger.valueOf(numSplits));
      for (int i = 1; i < numSplits; i++) {
        // NOTE: this means the last region gets all the slop.
        // This is not a big deal if we're assuming n << MAXHEX
        splits[i - 1] = s.add(sizeOfEachSplit.multiply(BigInteger.valueOf(i)));
      }

      if (inclusive) {
        BigInteger[] inclusiveSplitPoints = new BigInteger[numSplits + 1];
        inclusiveSplitPoints[0] = convertToBigInteger(start);
        inclusiveSplitPoints[numSplits] = convertToBigInteger(end);
        System.arraycopy(splits, 0, inclusiveSplitPoints, 1, splits.length);
        return convertToBytes(inclusiveSplitPoints);
      } else {
        return convertToBytes(splits);
      }
    }
The format of a DecimalStringSplit region boundary is the ASCII representation of reversed
sequential number, or any other uniformly distributed decimal value. Row are decimal-encoded
long values in the range <b>"00000000" =&gt; "99999999"</b> and are left-padded with zeros to
keep the same order lexicographically as if they were binary.
hbase-server/src/main/java/org/apache/hadoop/hbase/util/RegionSplitter.java