public static int CRC(final int poly, final int init, @NonNull final byte[] data, final int offset, final int length, final boolean refin, final boolean refout, final int xorout) {
		int crc = init;

		for (int i = offset; i < offset + length && i < data.length; ++i) {
			final byte b = data[i];
			for (int j = 0; j < 8; j++) {
				final int k = refin ? 7 - j : j;
				final boolean bit = ((b >> (7 - k) & 1) == 1);
				final boolean c15 = ((crc >> 15 & 1) == 1);
				crc <<= 1;
				if (c15 ^ bit) crc ^= poly;
			}
		}

		if (refout) {
			return (Integer.reverse(crc) >>> 16) ^ xorout;
		} else {
			return (crc ^ xorout) & 0xFFFF;
		}
	}
Calculates the CRC over given range of bytes from the block of data with given polynomial and initial value.
This method may also reverse input bytes and reverse output CRC.
<p>
See: <a href="http://www.zorc.breitbandkatze.de/crc.html">CRC Calculator</a>

@param poly   Polynomial used to calculate the CRC16.
@param init   Initial value to feed the buffer.
@param data   The input data block for computation.
@param offset Offset from where the range starts.
@param length Length of the range in bytes.
@param refin  True if the input data should be reversed.
@param refout True if the output data should be reversed.
@return CRC calculated with given parameters.
ble-common/src/main/java/no/nordicsemi/android/ble/common/util/CRC16.java