package cn.longhaul.test;

/**
 *  CRC16的校验算法工具类
 */
public class Crc16Util {

	/**
	 * 一个字节包含位的数量 8
	 */
	private static final int BITS_OF_BYTE = 8;
	/**
	 * 多项式
	 */
	private static final int POLYNOMIAL = 0x8408;
	/**
	 * 初始值
	 */
	private static final int INITIAL_VALUE = 0xFFFF;

	/**
	 * CRC16 编码
	 *
	 * @param bytes 编码内容
	 * @return 编码结果
	 */
	public static int crc16(int[] bytes) {
		int res = INITIAL_VALUE;
		for (int data : bytes) {
			res = res ^ data;
			for (int i = 0; i < BITS_OF_BYTE; i++) {
				res = (res & 0x0001) == 1 ? (res >> 1) ^ POLYNOMIAL : res >> 1;
			}
		}
		return revert(res);
	}

	/**
	 * 翻转16位的高八位和低八位字节
	 *
	 * @param src 翻转数字
	 * @return 翻转结果
	 */
	private static int revert(int src) {
		int lowByte = (src & 0xFF00) >> 8;
		int highByte = (src & 0x00FF) << 8;
		return lowByte | highByte;
	}


	/** 十六进制转为IntBytes
	 * @param s 十六进制串
	 * @return  int[] bytes
	 */
	public static int[] hexString2IntBytes(String s) {
		int[] bytes;
		bytes = new int[s.length() / 2];
		for (int i = 0; i < bytes.length; i++) {
			
			bytes[i] = (int) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);
		}
		return bytes;
	}

	public static void main(String[] args) throws Exception {
		int[] data = Crc16Util.hexString2IntBytes("18010206E28011700000020A7D001A0701000600000000");
		final int res = Crc16Util.crc16(data);
		final String hex = Integer.toHexString(res);
		System.out.print(hex);
	}

}
