package com.gyt.shr.util;

import java.io.ByteArrayOutputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;


/**
 * 金蝶EAS BOS 创建ID
 */
public class CreateIdUtil {



    /**
     * 根据十六进制 bosType 生成ID
     */
    public static String createID(String bosType)   {
        try {
            return createID(getBosTypeInt(bosType));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    // byte 转 int
    public static int bytesToInt(byte[] b) {
        int v0 = (b[0] & 0xff) << 24;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
        int v1 = (b[1] & 0xff) << 16;
        int v2 = (b[2] & 0xff) << 8;
        int v3 = (b[3] & 0xff);
        return v0 + v1 + v2 + v3;
    }

    /**
     * 生成BOSuuid,生成规则为 两个随机的 long 型数据,组合后加上 int 型的bostType ,经过Base64 转码生成的
     */
    public static String createID(int bosType) throws IOException {
        // 随机生成的数据不会重复么?
        // 以下代码是从BOS里抽出来的
        SecureRandom random = new SecureRandom();
        byte[] randomBytes = new byte[16];
        random.nextBytes(randomBytes);
        randomBytes[6] = (byte) (randomBytes[6] & 0xF);
        randomBytes[6] = (byte) (randomBytes[6] | 0x40);
        randomBytes[8] = (byte) (randomBytes[8] & 0x3F);
        randomBytes[8] = (byte) (randomBytes[8] | 0x80);
        long mostSigBits = 0L;
        long leastSigBits = 0L;
        for (int i = 0; i < 8; ++i) {
            mostSigBits = mostSigBits << 8 | randomBytes[i] & 0xFF;
        }
        for (int i = 8; i < 16; ++i) {
            leastSigBits = leastSigBits << 8 | randomBytes[i] & 0xFF;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutput out = new DataOutputStream(baos);
        out.writeLong(mostSigBits);
        out.writeLong(leastSigBits);
        out.writeInt(bosType);
        return   Base64.getEncoder().encodeToString(baos.toByteArray());

    }



    /**
     * 把十进制的 bosType 返回十六进制的 bosType,ID 经过base64解码后取最后4位生成int 型数据,转十六进制即可以得到bosType,然后可以通过bosType得到实体名
     */
    public static String getBosType(String id)   {
        byte[] result = new byte[0];
            result = Arrays.copyOfRange(java.util.Base64.getDecoder().decode(id), 16, 20);
        int type = bytesToInt(result);
        return Integer.toHexString(type).toUpperCase();
    }

    /**
     * 十六进制的 bosType 转十进制的  bosType
     */
    public static int getBosTypeInt(String bosType) {
        return Integer.valueOf(bosType, 16);
    }


 }
