Java生成銀聯(lián)PIN BLOCK

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

/**
 * 銀聯(lián)工具包
 */
public class UnionPayUtil {
    private static final int PIN_MIN_LENGTH = 4;
    private static final int PIN_MAX_LENGTH = 12;
    private static final int HEXADECIMAL = 16;
    /**
     * DES/3SDE算法PIN BLOCK大小為8
     * SM4算法PIN BLOCK大小為16
     */
    private static final int PIN_BLOCK_SIZE = 16;

    /**
     * 生成 PIN Block
     * @param pin
     * @return
     */
    private static byte[] pinBlock(String pin) {
        int pinLength = pin.length();
        if (pinLength < PIN_MIN_LENGTH || pinLength > PIN_MAX_LENGTH) {
            throw new IllegalArgumentException("Pin should be 4 to 12 digits long");
        }

        /**
         * PIN 格式 16BYTE 大小
         * 1BYTE PIN長(zhǎng)度 + 15BYTE Pin
         * Pin不足部分右補(bǔ)F
         */
        byte[] pinBlock = new byte[PIN_BLOCK_SIZE];
        //如果是奇數(shù)右補(bǔ)F轉(zhuǎn)換成如果不足12位右補(bǔ)F,補(bǔ)到12位長(zhǎng)度
        pin = StringUtils.rightPad(pin,PIN_MAX_LENGTH,'F');
        //先處理PIN BLOCK 長(zhǎng)度
        pinBlock[0] = (byte) pinLength;
        //處理PIN
        for (int i = 0; i <= pin.length() - 1; i = i + 2) {
            int pinBlockIndex = (i / 2) + 1;
            pinBlock[pinBlockIndex] = (byte) Integer.parseInt(pin.substring(i, i + 2), HEXADECIMAL);
        }

        /**
         * 不足32位補(bǔ),需要補(bǔ)的位長(zhǎng)度為PinBlock減去PIN長(zhǎng)度域的長(zhǎng)度和PIN數(shù)據(jù)長(zhǎng)度
         */

        int blockIndex = (pin.length() / 2) + 1;
        for (int i = blockIndex; i <= PIN_BLOCK_SIZE - 1; i++) {
            pinBlock[i] = (byte) 0xFF;
        }
        return pinBlock;
    }

    /**
     * 格式
     * 2BYTE %H0000
     * 14BYTE 取主賬號(hào)的右12位(不包括最右邊的校驗(yàn)位),主賬號(hào)不足12位左補(bǔ)0
     *
     * @param mAccNo 主賬號(hào)
     * @return
     */
    private static byte[] pan(String mAccNo) {
        /**
         * 不足12位左補(bǔ)0,后面要取右12位,不包括校驗(yàn)位,全長(zhǎng)是不足13位的就需要補(bǔ)
         */
        StringUtils.leftPad(mAccNo, 13, '0');
        byte[] panByte = new byte[PIN_BLOCK_SIZE];
        //截取右12位,包括校驗(yàn)位是13位
        String pan = StringUtils.left(StringUtils.right(mAccNo, 12 + 1), 12);
        /**
         * 2BYTE %H0000
         * 14BYTE 取主賬號(hào)的右12位(不包括最右邊的校驗(yàn)位),主賬號(hào)不足12位左補(bǔ)0
         */
        //初始化左邊為0區(qū)域
        int leftSize = PIN_BLOCK_SIZE - 12 / 2;
        for (int i = 0; i <= leftSize - 1; i++) {
            panByte[i] = (byte) 0x00;
        }
        int panIndex = 0;
        for (int i = leftSize; i <= PIN_BLOCK_SIZE - 1; i++, panIndex+=2) {
            String a = pan.substring(panIndex, panIndex + 2);
            panByte[i] = (byte) Integer.parseInt(a, HEXADECIMAL);
        }
        return panByte;
    }

    /**
     * SM4加密,并進(jìn)行轉(zhuǎn)16進(jìn)制計(jì)算
     *
     * @return
     */
    public static String encryptPin(String accNo, String pin, String key) {
        byte[] pinBlock = null;
        try {
            pinBlock = pinBlock(pin, accNo);
            byte[] keyBytes = ByteUtils.fromHexString(key);
            pinBlock = SM4Helper.encrypt(keyBytes,pinBlock);
            return ByteUtils.toHexString(pinBlock);
        } catch (Exception e) {
            return "";
        }
    }


    /**
     * @param pin    Personal Identification Number
     * @param mAccNo Main account number
     * @return
     */
    private static byte[] pinBlock(String pin, String mAccNo) {
        byte[] pingBlock = pinBlock(pin);
        byte[] pan = pan(mAccNo);
        byte[] tByte = new byte[PIN_BLOCK_SIZE];
        for (int i = 0; i < PIN_BLOCK_SIZE; i++) {
            tByte[i] = (byte) (pingBlock[i] ^ pan[i]);
        }
        return tByte;
    }

    public static void main(String[] args) {
        String key = "11111111111111111111111111111111";
        String pin = "123456";
        String accNo = "123456789012345678";
        String pinBlock = Hex.encodeHexString(pinBlock(pin, accNo));
        System.out.println(pinBlock);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容