package com.crm.rely.backend.util;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;


/**
 * @program: cwg-my-base
 * @description:
 * @author: houn
 * @create: 2019-05-07 11:08
 */
public class HAMCSHAUtil {
    /**
     * 定义加密方式
     * MAC算法可选以下多种算法
     * <pre>
     * HmacMD5
     * HmacSHA1
     * HmacSHA256
     * HmacSHA384
     * HmacSHA512
     * </pre>
     */
    private static final String HMAC_SHA_ALGORITHM = "HmacSHA1";

    private static final String HMAC_SHA256_ALGORITHM = "HmacSHA256";

    private static final String HMAC_SHA512_ALGORITHM = "HmacSHA512";

    public static String sha1HMAC(String data, String secret) {
        return shaHMAC(data, secret, HMAC_SHA_ALGORITHM);
    }

    public static String sha1HMAC(String data, byte[] secret) {
        return shaHMAC(data, secret, HMAC_SHA_ALGORITHM);
    }

    public static String sha256HMAC(String data, String secret) {
        return shaHMAC(data, secret, HMAC_SHA256_ALGORITHM);
    }

    public static String sha256HMAC(String data, byte[] secret) {
        return shaHMAC(data, secret, HMAC_SHA256_ALGORITHM);
    }

    public static String sha512HMAC(String data, String secret) throws Exception {
        return shaHMAC(data, secret, HMAC_SHA512_ALGORITHM);
    }

    public static String sha512HMACBase64(String data, String secret) {

        byte[] hash = shaHMACByte(data, secret, HMAC_SHA512_ALGORITHM);
        return Base64.encodeBase64String(hash);
    }

    public static String sha512HMAC(String data, byte[] secret) throws Exception {
        return shaHMAC(data, secret, HMAC_SHA512_ALGORITHM);
    }

    public static String sha256HMACBase64(String data, String secret) {

        byte[] hash = shaHMACByte(data, secret, HMAC_SHA256_ALGORITHM);
        return Base64.encodeBase64String(hash);
    }

    public static byte[] shaHMACByte(String data, String secret, String algorithm) {
        return shaHMACByte(data, secret.getBytes(), algorithm);
    }

    public static byte[] shaHMACByte(String data, byte[] secret, String algorithm) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(secret, algorithm);
            Mac mac = Mac.getInstance(algorithm);
            mac.init(signingKey);
            byte[] hash = mac.doFinal(data.getBytes());
            return hash;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String shaHMAC(String data, String secret, String algorithm) {
        byte[] re = shaHMACByte(data, secret, algorithm);
        return byte2hex(re);
    }

    public static String shaHMAC(String data, byte[] secret, String algorithm) {
        byte[] re = shaHMACByte(data, secret, algorithm);
        return byte2hex(re);
    }

    private static String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            // 以十六进制（基数 16）无符号整数形式返回一个整数参数的字符串表示形式。
            stmp = (Integer.toHexString(b[n] & 0xFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {

//            System.out.println(getSignature("{\"currency\":\"BTC\",\"foreign_id\":\"123456\"}", "AbCdEfG123456"));
//            String signature = sha512HMAC("amount=18000&currency=RMB&customer=10001&merchant=ME2333&txcode=TX3888",
//                    "bipipaykey");
//            System.out.println(signature);

            System.out.println(HAMCSHA256Util.HMACSHA256("count=100&created_time=2024-04-25 " +
                            "15:26:16&currency=USDT&merchant_order_no=PD202404251527169849_66753851&merchant_profit=0" +
                            ".00000000&nonce=1714030080312&platform_fee=0.60000000&side=BUY&status=COMPLETE",
                    "02ad904d8600b1f7d33823ba54b2f533983659c68c55da075f6d0948e4931625e9"));
            System.out.println(HAMCSHA256Util.HMACSHA256("count=96.02194813&created_time=2020-04-10%2010%3A29%3A58" +
                            "&currency=USDT&merchant_order_no=51116897781651&merchant_profit=0" +
                            ".00000000&nonce=1586488141021&order_no=undefined&platform_fee=0" +
                            ".28806584&side=BUY&status=CANCEL",
                    "02ad904d8600b1f7d33823ba54b2f533983659c68c55da075f6d0948e4931625e9"));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
