@Override
    public byte[][] split(int n) {
      Preconditions.checkArgument(lastRowInt.compareTo(firstRowInt) > 0,
        "last row (%s) is configured less than first row (%s)", lastRow, firstRow);
      // +1 to range because the last row is inclusive
      BigInteger range = lastRowInt.subtract(firstRowInt).add(BigInteger.ONE);
      Preconditions.checkState(range.compareTo(BigInteger.valueOf(n)) >= 0,
        "split granularity (%s) is greater than the range (%s)", n, range);

      BigInteger[] splits = new BigInteger[n - 1];
      BigInteger sizeOfEachSplit = range.divide(BigInteger.valueOf(n));
      for (int i = 1; i < n; 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] = firstRowInt.add(sizeOfEachSplit.multiply(BigInteger.valueOf(i)));
      }
      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