天天看點

國産加密SM3算法java實作

SM3.java

public class SM3 {

    public static final byte[] iv = { , (byte) , , , ,
            , (byte) , (byte) , , , , (byte) ,
            (byte) , (byte) , , , (byte) , , ,
            (byte) , (byte) , , , (byte) , (byte) ,
            (byte) , (byte) , , (byte) , (byte) , ,
             };

    public static int[] Tj = new int[];

    static
    {
        for (int i = ; i < ; i++)
        {
            Tj[i] = ;
        }

        for (int i = ; i < ; i++)
        {
            Tj[i] = ;
        }
    }

    public static byte[] CF(byte[] V, byte[] B)
    {
        int[] v, b;
        v = convert(V);
        b = convert(B);
        return convert(CF(v, b));
    }

    private static int[] convert(byte[] arr)
    {
        int[] out = new int[arr.length / ];
        byte[] tmp = new byte[];
        for (int i = ; i < arr.length; i += )
        {
            System.arraycopy(arr, i, tmp, , );
            out[i / ] = bigEndianByteToInt(tmp);
        }
        return out;
    }

    private static byte[] convert(int[] arr)
    {
        byte[] out = new byte[arr.length * ];
        byte[] tmp = null;
        for (int i = ; i < arr.length; i++)
        {
            tmp = bigEndianIntToByte(arr[i]);
            System.arraycopy(tmp, , out, i * , );
        }
        return out;
    }

    public static int[] CF(int[] V, int[] B)
    {
        int a, b, c, d, e, f, g, h;
        int ss1, ss2, tt1, tt2;
        a = V[];
        b = V[];
        c = V[];
        d = V[];
        e = V[];
        f = V[];
        g = V[];
        h = V[];

        /*System.out.println("IV: ");
        System.out.print(Integer.toHexString(a)+" ");
        System.out.print(Integer.toHexString(b)+" ");
        System.out.print(Integer.toHexString(c)+" ");
        System.out.print(Integer.toHexString(d)+" ");
        System.out.print(Integer.toHexString(e)+" ");
        System.out.print(Integer.toHexString(f)+" ");
        System.out.print(Integer.toHexString(g)+" ");
        System.out.print(Integer.toHexString(h)+" ");
        System.out.println("");
        System.out.println("");

        System.out.println("填充後的消息: ");
        for(int i=0; i<B.length; i++)
        {
            System.out.print(Integer.toHexString(B[i])+" ");
        }
        System.out.println("");
        System.out.println("");*/

        int[][] arr = expand(B);
        int[] w = arr[];
        int[] w1 = arr[];

        /*System.out.println("擴充後的消息: ");
        System.out.println("W0W1...W67");
        print(w);
        System.out.println("");
        System.out.println("W'0W'1...W'67");
        print(w1);
        System.out.println("疊代壓縮中間值: ");*/

        for (int j = ; j < ; j++)
        {
            ss1 = (bitCycleLeft(a, ) + e + bitCycleLeft(Tj[j], j));
            ss1 = bitCycleLeft(ss1, );
            ss2 = ss1 ^ bitCycleLeft(a, );
            tt1 = FFj(a, b, c, j) + d + ss2 + w1[j];
            tt2 = GGj(e, f, g, j) + h + ss1 + w[j];
            d = c;
            c = bitCycleLeft(b, );
            b = a;
            a = tt1;
            h = g;
            g = bitCycleLeft(f, );
            f = e;
            e = P0(tt2);

            /*System.out.print(j+" ");
            System.out.print(Integer.toHexString(a)+" ");
            System.out.print(Integer.toHexString(b)+" ");
            System.out.print(Integer.toHexString(c)+" ");
            System.out.print(Integer.toHexString(d)+" ");
            System.out.print(Integer.toHexString(e)+" ");
            System.out.print(Integer.toHexString(f)+" ");
            System.out.print(Integer.toHexString(g)+" ");
            System.out.print(Integer.toHexString(h)+" ");
            System.out.println("");*/
        }
//      System.out.println("");

        int[] out = new int[];
        out[] = a ^ V[];
        out[] = b ^ V[];
        out[] = c ^ V[];
        out[] = d ^ V[];
        out[] = e ^ V[];
        out[] = f ^ V[];
        out[] = g ^ V[];
        out[] = h ^ V[];

        return out;
    }

    private static int[][] expand(int[] B)
    {
        int W[] = new int[];
        int W1[] = new int[];
        for (int i = ; i < B.length; i++)
        {
            W[i] = B[i];
        }

        for (int i = ; i < ; i++)
        {
            W[i] = P1(W[i - ] ^ W[i - ] ^ bitCycleLeft(W[i - ], ))
                    ^ bitCycleLeft(W[i - ], ) ^ W[i - ];
        }

        for (int i = ; i < ; i++)
        {
            W1[i] = W[i] ^ W[i + ];
        }

        int arr[][] = new int[][] { W, W1 };
        return arr;
    }

    private static byte[] bigEndianIntToByte(int num)
    {
        return back(Util.intToBytes(num));
    }

    private static int bigEndianByteToInt(byte[] bytes)
    {
        return Util.byteToInt(back(bytes));
    }

    private static int FFj(int X, int Y, int Z, int j)
    {
        if (j >=  && j <= )
        {
            return FF1j(X, Y, Z);
        }
        else
        {
            return FF2j(X, Y, Z);
        }
    }

    private static int GGj(int X, int Y, int Z, int j)
    {
        if (j >=  && j <= )
        {
            return GG1j(X, Y, Z);
        }
        else
        {
            return GG2j(X, Y, Z);
        }
    }

    // 邏輯位運算函數
    private static int FF1j(int X, int Y, int Z)
    {
        int tmp = X ^ Y ^ Z;
        return tmp;
    }

    private static int FF2j(int X, int Y, int Z)
    {
        int tmp = ((X & Y) | (X & Z) | (Y & Z));
        return tmp;
    }

    private static int GG1j(int X, int Y, int Z)
    {
        int tmp = X ^ Y ^ Z;
        return tmp;
    }

    private static int GG2j(int X, int Y, int Z)
    {
        int tmp = (X & Y) | (~X & Z);
        return tmp;
    }

    private static int P0(int X)
    {
        int y = rotateLeft(X, );
        y = bitCycleLeft(X, );
        int z = rotateLeft(X, );
        z = bitCycleLeft(X, );
        int t = X ^ y ^ z;
        return t;
    }

    private static int P1(int X)
    {
        int t = X ^ bitCycleLeft(X, ) ^ bitCycleLeft(X, );
        return t;
    }

    /**
     * 對最後一個分組位元組資料padding
     *
     * @param in
     * @param bLen
     *            分組個數
     * @return
     */
    public static byte[] padding(byte[] in, int bLen)
    {
        int k =  - ( * in.length + ) % ;
        if (k < )
        {
            k =  - ( * in.length + ) % ;
        }
        k += ;
        byte[] padd = new byte[k / ];
        padd[] = (byte) ;
        long n = in.length *  + bLen * ;
        byte[] out = new byte[in.length + k /  +  / ];
        int pos = ;
        System.arraycopy(in, , out, , in.length);
        pos += in.length;
        System.arraycopy(padd, , out, pos, padd.length);
        pos += padd.length;
        byte[] tmp = back(Util.longToBytes(n));
        System.arraycopy(tmp, , out, pos, tmp.length);
        return out;
    }

    /**
     * 位元組數組逆序
     *
     * @param in
     * @return
     */
    private static byte[] back(byte[] in)
    {
        byte[] out = new byte[in.length];
        for (int i = ; i < out.length; i++)
        {
            out[i] = in[out.length - i - ];
        }

        return out;
    }

    public static int rotateLeft(int x, int n)
    {
        return (x << n) | (x >> ( - n));
    }

    private static int bitCycleLeft(int n, int bitLen)
    {
        bitLen %= ;
        byte[] tmp = bigEndianIntToByte(n);
        int byteLen = bitLen / ;
        int len = bitLen % ;
        if (byteLen > )
        {
            tmp = byteCycleLeft(tmp, byteLen);
        }

        if (len > )
        {
            tmp = bitSmall8CycleLeft(tmp, len);
        }

        return bigEndianByteToInt(tmp);
    }

    private static byte[] bitSmall8CycleLeft(byte[] in, int len)
    {
        byte[] tmp = new byte[in.length];
        int t1, t2, t3;
        for (int i = ; i < tmp.length; i++)
        {
            t1 = (byte) ((in[i] & ) << len);
            t2 = (byte) ((in[(i + ) % tmp.length] & ) >> ( - len));
            t3 = (byte) (t1 | t2);
            tmp[i] = (byte) t3;
        }

        return tmp;
    }

    private static byte[] byteCycleLeft(byte[] in, int byteLen)
    {
        byte[] tmp = new byte[in.length];
        System.arraycopy(in, byteLen, tmp, , in.length - byteLen);
        System.arraycopy(in, , tmp, in.length - byteLen, byteLen);
        return tmp;
    }

    /*private static void print(int[] arr)
    {
        for (int i = 0; i < arr.length; i++)
        {
            System.out.print(Integer.toHexString(arr[i]) + " ");
            if ((i + 1) % 16 == 0)
            {
                System.out.println();
            }
        }
        System.out.println();
    }*/
}
           

SM3Digest.java

import org.bouncycastle.util.encoders.Hex;

public class SM3Digest
{
    /** SM3值的長度 */
    private static final int BYTE_LENGTH = ;

    /** SM3分組長度 */
    private static final int BLOCK_LENGTH = ;

    /** 緩沖區長度 */
    private static final int BUFFER_LENGTH = BLOCK_LENGTH * ;

    /** 緩沖區 */
    private byte[] xBuf = new byte[BUFFER_LENGTH];

    /** 緩沖區偏移量 */
    private int xBufOff;

    /** 初始向量 */
    private byte[] V = SM3.iv.clone();

    private int cntBlock = ;

    public SM3Digest() {
    }

    public SM3Digest(SM3Digest t)
    {
        System.arraycopy(t.xBuf, , this.xBuf, , t.xBuf.length);
        this.xBufOff = t.xBufOff;
        System.arraycopy(t.V, , this.V, , t.V.length);
    }

    /**
     * SM3結果輸出
     *
     * @param out 儲存SM3結構的緩沖區
     * @param outOff 緩沖區偏移量
     * @return
     */
    public int doFinal(byte[] out, int outOff)
    {
        byte[] tmp = doFinal();
        System.arraycopy(tmp, , out, , tmp.length);
        return BYTE_LENGTH;
    }

    public void reset()
    {
        xBufOff = ;
        cntBlock = ;
        V = SM3.iv.clone();
    }

    /**
     * 明文輸入
     *
     * @param in
     *            明文輸入緩沖區
     * @param inOff
     *            緩沖區偏移量
     * @param len
     *            明文長度
     */
    public void update(byte[] in, int inOff, int len)
    {
        int partLen = BUFFER_LENGTH - xBufOff;
        int inputLen = len;
        int dPos = inOff;
        if (partLen < inputLen)
        {
            System.arraycopy(in, dPos, xBuf, xBufOff, partLen);
            inputLen -= partLen;
            dPos += partLen;
            doUpdate();
            while (inputLen > BUFFER_LENGTH)
            {
                System.arraycopy(in, dPos, xBuf, , BUFFER_LENGTH);
                inputLen -= BUFFER_LENGTH;
                dPos += BUFFER_LENGTH;
                doUpdate();
            }
        }

        System.arraycopy(in, dPos, xBuf, xBufOff, inputLen);
        xBufOff += inputLen;
    }

    private void doUpdate()
    {
        byte[] B = new byte[BLOCK_LENGTH];
        for (int i = ; i < BUFFER_LENGTH; i += BLOCK_LENGTH)
        {
            System.arraycopy(xBuf, i, B, , B.length);
            doHash(B);
        }
        xBufOff = ;
    }

    private void doHash(byte[] B)
    {
        byte[] tmp = SM3.CF(V, B);
        System.arraycopy(tmp, , V, , V.length);
        cntBlock++;
    }

    private byte[] doFinal()
    {
        byte[] B = new byte[BLOCK_LENGTH];
        byte[] buffer = new byte[xBufOff];
        System.arraycopy(xBuf, , buffer, , buffer.length);
        byte[] tmp = SM3.padding(buffer, cntBlock);
        for (int i = ; i < tmp.length; i += BLOCK_LENGTH)
        {
            System.arraycopy(tmp, i, B, , B.length);
            doHash(B);
        }
        return V;
    }

    public void update(byte in)
    {
        byte[] buffer = new byte[] { in };
        update(buffer, , );
    }

    public int getDigestSize()
    {
        return BYTE_LENGTH;
    }

    public static void main(String[] args) {
        byte[] md = new byte[];
        byte[] md2 = new byte[];
        byte[] msg1 = "abc".getBytes();
        byte[] msg2 = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd".getBytes();


        SM3Digest sm3 = new SM3Digest();
//      sm3.update(msg1, 0, msg1.length);
//      sm3.doFinal(md, 0);
//      String s = new String(Hex.encode(md));
//      System.out.println("msg1:" + s);

        sm3.update(msg2, , msg2.length);
        sm3.doFinal(md2, );
        String s2 = new String(Hex.encode(md2));
        System.out.println("msg2:" + s2);

    }
}
           

Util.java

import java.math.BigInteger;

public class Util
{
    /**
     * 整形轉換成網絡傳輸的位元組流(位元組數組)型資料
     *
     * @param num 一個整型資料
     * @return 4個位元組的自己數組
     */
    public static byte[] intToBytes(int num)
    {
        byte[] bytes = new byte[];
        bytes[] = (byte) ( & (num >> ));
        bytes[] = (byte) ( & (num >> ));
        bytes[] = (byte) ( & (num >> ));
        bytes[] = (byte) ( & (num >> ));
        return bytes;
    }

    /**
     * 四個位元組的位元組資料轉換成一個整形資料
     *
     * @param bytes 4個位元組的位元組數組
     * @return 一個整型資料
     */
    public static int byteToInt(byte[] bytes)
    {
        int num = ;
        int temp;
        temp = ( & (bytes[])) << ;
        num = num | temp;
        temp = ( & (bytes[])) << ;
        num = num | temp;
        temp = ( & (bytes[])) << ;
        num = num | temp;
        temp = ( & (bytes[])) << ;
        num = num | temp;
        return num;
    }

    /**
     * 長整形轉換成網絡傳輸的位元組流(位元組數組)型資料
     *
     * @param num 一個長整型資料
     * @return 4個位元組的自己數組
     */
    public static byte[] longToBytes(long num)
    {
        byte[] bytes = new byte[];
        for (int i = ; i < ; i++)
        {
            bytes[i] = (byte) ( & (num >> (i * )));
        }

        return bytes;
    }

    /**
     * 大數字轉換位元組流(位元組數組)型資料
     *
     * @param n
     * @return
     */
    public static byte[] byteConvert32Bytes(BigInteger n)
    {
        byte tmpd[] = (byte[])null;
        if(n == null)
        {
            return null;
        }

        if(n.toByteArray().length == )
        {
            tmpd = new byte[];
            System.arraycopy(n.toByteArray(), , tmpd, , );
        }
        else if(n.toByteArray().length == )
        {
            tmpd = n.toByteArray();
        }
        else
        {
            tmpd = new byte[];
            for(int i = ; i <  - n.toByteArray().length; i++)
            {
                tmpd[i] = ;
            }
            System.arraycopy(n.toByteArray(), , tmpd,  - n.toByteArray().length, n.toByteArray().length);
        }
        return tmpd;
    }

    /**
     * 換位元組流(位元組數組)型資料轉大數字
     *
     * @param b
     * @return
     */
    public static BigInteger byteConvertInteger(byte[] b)
    {
        if (b[] < )
        {
            byte[] temp = new byte[b.length + ];
            temp[] = ;
            System.arraycopy(b, , temp, , b.length);
            return new BigInteger(temp);
        }
        return new BigInteger(b);
    }

    /**
     * 根據位元組數組獲得值(十六進制數字)
     *
     * @param bytes
     * @return
     */
    public static String getHexString(byte[] bytes)
    {
        return getHexString(bytes, true);
    }

    /**
     * 根據位元組數組獲得值(十六進制數字)
     *
     * @param bytes
     * @param upperCase
     * @return
     */
    public static String getHexString(byte[] bytes, boolean upperCase)
    {
        String ret = "";
        for (int i = ; i < bytes.length; i++)
        {
            ret += Integer.toString((bytes[i] & ) + , ).substring();
        }
        return upperCase ? ret.toUpperCase() : ret;
    }

    /**
     * 列印十六進制字元串
     *
     * @param bytes
     */
    public static void printHexString(byte[] bytes)
    {
        for (int i = ; i < bytes.length; i++)
        {
            String hex = Integer.toHexString(bytes[i] & );
            if (hex.length() == )
            {
                hex = '0' + hex;
            }
            System.out.print("0x" + hex.toUpperCase() + ",");
        }
        System.out.println("");
    }

    /**
     * Convert hex string to byte[]
     *
     * @param hexString
     *            the hex string
     * @return byte[]
     */
    public static byte[] hexStringToBytes(String hexString)
    {
        if (hexString == null || hexString.equals(""))
        {
            return null;
        }

        hexString = hexString.toUpperCase();
        int length = hexString.length() / ;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = ; i < length; i++)
        {
            int pos = i * ;
            d[i] = (byte) (charToByte(hexChars[pos]) <<  | charToByte(hexChars[pos + ]));
        }
        return d;
    }

    /**
     * Convert char to byte
     *
     * @param c
     *            char
     * @return byte
     */
    public static byte charToByte(char c)
    {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /**
     * 用于建立十六進制字元的輸出的小寫字元數組
     */
    private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * 用于建立十六進制字元的輸出的大寫字元數組
     */
    private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    /**
     * 将位元組數組轉換為十六進制字元數組
     *
     * @param data byte[]
     * @return 十六進制char[]
     */
    public static char[] encodeHex(byte[] data) {
        return encodeHex(data, true);
    }

    /**
     * 将位元組數組轉換為十六進制字元數組
     *
     * @param data        byte[]
     * @param toLowerCase <code>true</code> 傳換成小寫格式 , <code>false</code> 傳換成大寫格式
     * @return 十六進制char[]
     */
    public static char[] encodeHex(byte[] data, boolean toLowerCase) {
        return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
    }

    /**
     * 将位元組數組轉換為十六進制字元數組
     *
     * @param data     byte[]
     * @param toDigits 用于控制輸出的char[]
     * @return 十六進制char[]
     */
    protected static char[] encodeHex(byte[] data, char[] toDigits) {
        int l = data.length;
        char[] out = new char[l << ];
        // two characters form the hex value.
        for (int i = , j = ; i < l; i++) {
            out[j++] = toDigits[( & data[i]) >>> ];
            out[j++] = toDigits[ & data[i]];
        }
        return out;
    }

    /**
     * 将位元組數組轉換為十六進制字元串
     *
     * @param data byte[]
     * @return 十六進制String
     */
    public static String encodeHexString(byte[] data) {
        return encodeHexString(data, true);
    }

    /**
     * 将位元組數組轉換為十六進制字元串
     *
     * @param data        byte[]
     * @param toLowerCase <code>true</code> 傳換成小寫格式 , <code>false</code> 傳換成大寫格式
     * @return 十六進制String
     */
    public static String encodeHexString(byte[] data, boolean toLowerCase) {
        return encodeHexString(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
    }

    /**
     * 将位元組數組轉換為十六進制字元串
     *
     * @param data     byte[]
     * @param toDigits 用于控制輸出的char[]
     * @return 十六進制String
     */
    protected static String encodeHexString(byte[] data, char[] toDigits) {
        return new String(encodeHex(data, toDigits));
    }

    /**
     * 将十六進制字元數組轉換為位元組數組
     *
     * @param data 十六進制char[]
     * @return byte[]
     * @throws RuntimeException 如果源十六進制字元數組是一個奇怪的長度,将抛出運作時異常
     */
    public static byte[] decodeHex(char[] data) {
        int len = data.length;

        if ((len & ) != ) {
            throw new RuntimeException("Odd number of characters.");
        }

        byte[] out = new byte[len >> ];

        // two characters form the hex value.
        for (int i = , j = ; j < len; i++) {
            int f = toDigit(data[j], j) << ;
            j++;
            f = f | toDigit(data[j], j);
            j++;
            out[i] = (byte) (f & );
        }

        return out;
    }

    /**
     * 将十六進制字元轉換成一個整數
     *
     * @param ch    十六進制char
     * @param index 十六進制字元在字元數組中的位置
     * @return 一個整數
     * @throws RuntimeException 當ch不是一個合法的十六進制字元時,抛出運作時異常
     */
    protected static int toDigit(char ch, int index) {
        int digit = Character.digit(ch, );
        if (digit == -) {
            throw new RuntimeException("Illegal hexadecimal character " + ch
                    + " at index " + index);
        }
        return digit;
    }

    /**
     * 數字字元串轉ASCII碼字元串
     *
     * @param content
     *            字元串
     * @return ASCII字元串
     */
    public static String StringToAsciiString(String content) {
        String result = "";
        int max = content.length();
        for (int i = ; i < max; i++) {
            char c = content.charAt(i);
            String b = Integer.toHexString(c);
            result = result + b;
        }
        return result;
    }

    /**
     * 十六進制轉字元串
     *
     * @param hexString
     *            十六進制字元串
     * @param encodeType
     *            編碼類型4:Unicode,2:普通編碼
     * @return 字元串
     */
    public static String hexStringToString(String hexString, int encodeType) {
        String result = "";
        int max = hexString.length() / encodeType;
        for (int i = ; i < max; i++) {
            char c = (char) hexStringToAlgorism(hexString
                    .substring(i * encodeType, (i + ) * encodeType));
            result += c;
        }
        return result;
    }

    /**
     * 十六進制字元串裝十進制
     *
     * @param hex
     *            十六進制字元串
     * @return 十進制數值
     */
    public static int hexStringToAlgorism(String hex) {
        hex = hex.toUpperCase();
        int max = hex.length();
        int result = ;
        for (int i = max; i > ; i--) {
            char c = hex.charAt(i - );
            int algorism = ;
            if (c >= '0' && c <= '9') {
                algorism = c - '0';
            } else {
                algorism = c - ;
            }
            result += Math.pow(, max - i) * algorism;
        }
        return result;
    }

    /**
     * 十六轉二進制
     *
     * @param hex
     *            十六進制字元串
     * @return 二進制字元串
     */
    public static String hexStringToBinary(String hex) {
        hex = hex.toUpperCase();
        String result = "";
        int max = hex.length();
        for (int i = ; i < max; i++) {
            char c = hex.charAt(i);
            switch (c) {
                case '0':
                    result += "0000";
                    break;
                case '1':
                    result += "0001";
                    break;
                case '2':
                    result += "0010";
                    break;
                case '3':
                    result += "0011";
                    break;
                case '4':
                    result += "0100";
                    break;
                case '5':
                    result += "0101";
                    break;
                case '6':
                    result += "0110";
                    break;
                case '7':
                    result += "0111";
                    break;
                case '8':
                    result += "1000";
                    break;
                case '9':
                    result += "1001";
                    break;
                case 'A':
                    result += "1010";
                    break;
                case 'B':
                    result += "1011";
                    break;
                case 'C':
                    result += "1100";
                    break;
                case 'D':
                    result += "1101";
                    break;
                case 'E':
                    result += "1110";
                    break;
                case 'F':
                    result += "1111";
                    break;
            }
        }
        return result;
    }

    /**
     * ASCII碼字元串轉數字字元串
     *
     * @param content
     *            ASCII字元串
     * @return 字元串
     */
    public static String AsciiStringToString(String content) {
        String result = "";
        int length = content.length() / ;
        for (int i = ; i < length; i++) {
            String c = content.substring(i * , i *  + );
            int a = hexStringToAlgorism(c);
            char b = (char) a;
            String d = String.valueOf(b);
            result += d;
        }
        return result;
    }

    /**
     * 将十進制轉換為指定長度的十六進制字元串
     *
     * @param algorism
     *            int 十進制數字
     * @param maxLength
     *            int 轉換後的十六進制字元串長度
     * @return String 轉換後的十六進制字元串
     */
    public static String algorismToHexString(int algorism, int maxLength) {
        String result = "";
        result = Integer.toHexString(algorism);

        if (result.length() %  == ) {
            result = "0" + result;
        }
        return patchHexString(result.toUpperCase(), maxLength);
    }

    /**
     * 位元組數組轉為普通字元串(ASCII對應的字元)
     *
     * @param bytearray
     *            byte[]
     * @return String
     */
    public static String byteToString(byte[] bytearray) {
        String result = "";
        char temp;

        int length = bytearray.length;
        for (int i = ; i < length; i++) {
            temp = (char) bytearray[i];
            result += temp;
        }
        return result;
    }

    /**
     * 二進制字元串轉十進制
     *
     * @param binary
     *            二進制字元串
     * @return 十進制數值
     */
    public static int binaryToAlgorism(String binary) {
        int max = binary.length();
        int result = ;
        for (int i = max; i > ; i--) {
            char c = binary.charAt(i - );
            int algorism = c - '0';
            result += Math.pow(, max - i) * algorism;
        }
        return result;
    }

    /**
     * 十進制轉換為十六進制字元串
     *
     * @param algorism
     *            int 十進制的數字
     * @return String 對應的十六進制字元串
     */
    public static String algorismToHEXString(int algorism) {
        String result = "";
        result = Integer.toHexString(algorism);

        if (result.length() %  == ) {
            result = "0" + result;

        }
        result = result.toUpperCase();

        return result;
    }

    /**
     * HEX字元串前補0,主要用于長度位數不足。
     *
     * @param str
     *            String 需要補充長度的十六進制字元串
     * @param maxLength
     *            int 補充後十六進制字元串的長度
     * @return 補充結果
     */
    static public String patchHexString(String str, int maxLength) {
        String temp = "";
        for (int i = ; i < maxLength - str.length(); i++) {
            temp = "0" + temp;
        }
        str = (temp + str).substring(, maxLength);
        return str;
    }

    /**
     * 将一個字元串轉換為int
     *
     * @param s
     *            String 要轉換的字元串
     * @param defaultInt
     *            int 如果出現異常,預設傳回的數字
     * @param radix
     *            int 要轉換的字元串是什麼進制的,如16 8 10.
     * @return int 轉換後的數字
     */
    public static int parseToInt(String s, int defaultInt, int radix) {
        int i = ;
        try {
            i = Integer.parseInt(s, radix);
        } catch (NumberFormatException ex) {
            i = defaultInt;
        }
        return i;
    }

    /**
     * 将一個十進制形式的數字字元串轉換為int
     *
     * @param s
     *            String 要轉換的字元串
     * @param defaultInt
     *            int 如果出現異常,預設傳回的數字
     * @return int 轉換後的數字
     */
    public static int parseToInt(String s, int defaultInt) {
        int i = ;
        try {
            i = Integer.parseInt(s);
        } catch (NumberFormatException ex) {
            i = defaultInt;
        }
        return i;
    }

    /**
     * 十六進制串轉化為byte數組
     *
     * @return the array of byte
     */
    public static byte[] hexToByte(String hex)
            throws IllegalArgumentException {
        if (hex.length() %  != ) {
            throw new IllegalArgumentException();
        }
        char[] arr = hex.toCharArray();
        byte[] b = new byte[hex.length() / ];
        for (int i = , j = , l = hex.length(); i < l; i++, j++) {
            String swap = "" + arr[i++] + arr[i];
            int byteint = Integer.parseInt(swap, ) & ;
            b[j] = new Integer(byteint).byteValue();
        }
        return b;
    }

    /**
     * 位元組數組轉換為十六進制字元串
     *
     * @param b
     *            byte[] 需要轉換的位元組數組
     * @return String 十六進制字元串
     */
    public static String byteToHex(byte b[]) {
        if (b == null) {
            throw new IllegalArgumentException(
                    "Argument b ( byte array ) is null! ");
        }
        String hs = "";
        String stmp = "";
        for (int n = ; n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & );
            if (stmp.length() == ) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }

    public static byte[] subByte(byte[] input, int startIndex, int length) {
        byte[] bt = new byte[length];
        for (int i = ; i < length; i++) {
            bt[i] = input[i + startIndex];
        }
        return bt;
    }
}