/*
 * Copyright 2016 E-System LLC
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.es.lib.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;

/**
 * @author Zuzoev Dmitry - zuzoev.d@ext-system.com
 * @since 10.04.15
 */
public final class HashUtil {

    private static final Logger LOG = LoggerFactory.getLogger(HashUtil.class);
    private static final String HEXES = "0123456789abcdef";

    private HashUtil() {
    }

    public static String hash(byte[] value, String algorithm) {
        if (value == null) {
            return null;
        }
        try {
            MessageDigest digest = MessageDigest.getInstance(algorithm);
            digest.update(value);
            return getHex(digest.digest());
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return null;
        }
    }

    public static String hash(String value, String algorithm) {
        if (value == null) {
            return null;
        }
        try {
            return hash(value.getBytes(Constant.DEFAULT_ENCODING), algorithm);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return null;
        }
    }

    public static String md5(String value) {
        return hash(value, "MD5");
    }

    public static String md5(byte[] value) {
        return hash(value, "MD5");
    }

    public static boolean isCorrect(final String text, final String hash) {
        return md5(text).equals(hash);
    }

    public static String getHex(byte[] raw) {
        if (raw == null) {
            return null;
        }
        final StringBuilder hex = new StringBuilder(0x2 * raw.length);
        for (final byte b : raw) {
            hex.append(HEXES.charAt((b & 240) >> 0x4)).append(HEXES.charAt(b & 15));
        }
        return hex.toString();
    }

    public static int crc16(final byte[] buffer) {
        int crc = 0xFFFF;
        for (byte aBuffer : buffer) {
            crc = ((crc >>> 8) | (crc << 8)) & 0xFFFF;
            crc ^= (aBuffer & 0xFF);
            crc ^= ((crc & 0xFF) >> 4);
            crc ^= (crc << 12) & 0xFFFF;
            crc ^= ((crc & 0xFF) << 5) & 0xFFFF;
        }
        crc &= 0xFFFF;
        return crc;
    }

    public static int CRC16CCITT(byte[] data) { return CRC16CCITT(data, 0, 0); }

    public static int CRC16CCITT(byte[] data, int skipIndex, int skipLen) {
        int crc = 0xFFFF;          // init
        int polynom = 0x1021;   // 0001 0000 0010 0001
        for (int i = 0; i < data.length; i++) {
            if (i >= skipIndex && i < skipIndex + skipLen) {
                continue;
            }
            for (int j = 0; j < 8; j++) {
                boolean bit = ((data[i] >> (7 - j) & 1) == 1);
                boolean c15 = ((crc >> 15 & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit) crc ^= polynom;
            }
        }
        crc &= 0xFFFF;
        return crc;
    }

    public static int XOR(byte[] data) { return XOR(data, 0, 0); }

    public static int XOR(byte[] data, int skipIndex, int skipLen) {
        return XOR(data, skipIndex, skipLen, data.length);
    }

    public static int XOR(byte[] data, int skipIndex, int skipLen, int lastIdx) {
        byte res = 0x00;
        for (int i = 0; i < lastIdx; i++) {
            if (i >= skipIndex && i < skipIndex + skipLen) {
                continue;
            }
            res ^= data[i];
        }
        return res;
    }
}

@@ -2825,34 +2825,34 @@
  static int 
-CRC16CCITT
+crc16ccitt
 (byte%5B%5D data
@@ -2862,26 +2862,26 @@
  return 
-CRC16CCITT
+crc16ccitt
 (data, 0
@@ -2915,18 +2915,18 @@
 int 
-CRC16CCITT
+crc16ccitt
 (byt
@@ -3533,35 +3533,35 @@
 blic static int 
-XOR
+xor
 (byte%5B%5D data) %7B 
@@ -3563,27 +3563,27 @@
 a) %7B return 
-XOR
+xor
 (data, 0, 0)
@@ -3601,35 +3601,35 @@
 blic static int 
-XOR
+xor
 (byte%5B%5D data, in
@@ -3671,19 +3671,19 @@
  return 
-XOR
+xor
 (data, s
@@ -3748,11 +3748,11 @@
 int 
-XOR
+xor
 (byt

Rename crc16 methods