天天看點

Java實作國密算法SM2,SM3,SM4,并且實作ECB和CBC模式

代碼中實作了電碼本ECB模式和密文分組連接配接CBC模式,SM3.java和SM4.java為算法實作類,utils的都是根據實作類寫的工具,可以根據需要調用雜湊算法SM3的雜湊功能獲得雜湊值。

SM4.java中

sm4_crypt_ecb(SM4_Context ctx, byte[] input)      ECB模式加解密方法,根據密鑰判斷加解密功能

sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input)      CBC模式加解密方法,根據密鑰判斷加解密功能

加密解密通過如下方法:

sm4_setkey_enc(SM4_Context ctx, byte[] key)  設定加密密鑰調用上述方法,實作加密

sm4_setkey_dec(SM4_Context ctx, byte[] key)  設定解密密鑰調用上述方法,實作解密

需要導入的包為bcprov-jdk16  我用的版本是bcprov-jdk16-1.46

maven中配置依賴:

<dependency>

    <groupId>org.bouncycastle</groupId>

    <artifactId></artifactId>

    <version>1.46</version>

</dependency>

package中class目錄如下:

chiper.java

import java.math.BigInteger;  

import org.bouncycastle.crypto.AsymmetricCipherKeyPair;  

import org.bouncycastle.crypto.params.ECPrivateKeyParameters;  

import org.bouncycastle.crypto.params.ECPublicKeyParameters;  

import org.bouncycastle.math.ec.ECPoint; 

public class Cipher {

     private int ct;  

        private ECPoint p2;  

        private SM3Digest sm3keybase;  

        private SM3Digest sm3c3;  

        private byte key[];  

        private byte keyOff;  

        public Cipher()   

        {  

            this.ct = 1;  

            this.key = new byte[32];  

            this.keyOff = 0;  

        }  

        private void Reset()   

        {  

            this.sm3keybase = new SM3Digest();  

            this.sm3c3 = new SM3Digest();  

            byte p[] = Util.byteConvert32Bytes(p2.getX().toBigInteger());  

            this.sm3keybase.update(p, 0, p.length);  

            this.sm3c3.update(p, 0, p.length);  

            p = Util.byteConvert32Bytes(p2.getY().toBigInteger());  

            this.sm3keybase.update(p, 0, p.length);  

            this.ct = 1;  

            NextKey();  

        }  

        private void NextKey()   

        {  

            SM3Digest sm3keycur = new SM3Digest(this.sm3keybase);  

            sm3keycur.update((byte) (ct >> 24 & 0xff));  

            sm3keycur.update((byte) (ct >> 16 & 0xff));  

            sm3keycur.update((byte) (ct >> 8 & 0xff));  

            sm3keycur.update((byte) (ct & 0xff));  

            sm3keycur.doFinal(key, 0);  

            this.keyOff = 0;  

            this.ct++;  

        }  

        public ECPoint Init_enc(SM2 sm2, ECPoint userKey)   

        {  

            AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair();  

            ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate();  

            ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic();  

            BigInteger k = ecpriv.getD();  

            ECPoint c1 = ecpub.getQ();  

            this.p2 = userKey.multiply(k);  

            Reset();  

            return c1;  

        }  

        public void Encrypt(byte data[])   

        {  

            this.sm3c3.update(data, 0, data.length);  

            for (int i = 0; i < data.length; i++)   

            {  

                if (keyOff == key.length)  

                {  

                    NextKey();  

                }  

                data[i] ^= key[keyOff++];  

            }  

        }  

        public void Init_dec(BigInteger userD, ECPoint c1)  

        {  

            this.p2 = c1.multiply(userD);  

            Reset();  

        }  

        public void Decrypt(byte data[])   

        {  

            for (int i = 0; i < data.length; i++)  

            {  

                if (keyOff == key.length)  

                {  

                    NextKey();  

                }  

                data[i] ^= key[keyOff++];  

            }  

            this.sm3c3.update(data, 0, data.length);  

        }  

        public void Dofinal(byte c3[])   

        {  

            byte p[] = Util.byteConvert32Bytes(p2.getY().toBigInteger());  

            this.sm3c3.update(p, 0, p.length);  

            this.sm3c3.doFinal(c3, 0);  

            Reset();  

        }  

}

SM2.java

import java.math.BigInteger;  

import java.security.SecureRandom;  

import org.bouncycastle.crypto.generators.ECKeyPairGenerator;  

import org.bouncycastle.crypto.params.ECDomainParameters;  

import org.bouncycastle.crypto.params.ECKeyGenerationParameters;  

import org.bouncycastle.math.ec.ECCurve;  

import org.bouncycastle.math.ec.ECFieldElement;  

import org.bouncycastle.math.ec.ECPoint;  

import org.bouncycastle.math.ec.ECFieldElement.Fp;  

public class SM2 {

     //測試參數  

//  public static final String[] ecc_param = {  

//      "8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3",   

//      "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498",   

//      "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A",   

//      "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7",   

//      "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D",   

//      "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2"   

//  };  

    //正式參數  

    public static String[] ecc_param = {   

        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",  

        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",  

        "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",  

        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",  

        "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",  

        "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"  

    };  

    public static SM2 Instance()   

    {  

        return new SM2();  

    }  

    public final BigInteger ecc_p;  

    public final BigInteger ecc_a;  

    public final BigInteger ecc_b;  

    public final BigInteger ecc_n;  

    public final BigInteger ecc_gx;  

    public final BigInteger ecc_gy;  

    public final ECCurve ecc_curve;  

    public final ECPoint ecc_point_g;  

    public final ECDomainParameters ecc_bc_spec;  

    public final ECKeyPairGenerator ecc_key_pair_generator;  

    public final ECFieldElement ecc_gx_fieldelement;  

    public final ECFieldElement ecc_gy_fieldelement;  

    public SM2()   

    {  

        this.ecc_p = new BigInteger(ecc_param[0], 16);  

        this.ecc_a = new BigInteger(ecc_param[1], 16);  

        this.ecc_b = new BigInteger(ecc_param[2], 16);  

        this.ecc_n = new BigInteger(ecc_param[3], 16);  

        this.ecc_gx = new BigInteger(ecc_param[4], 16);  

        this.ecc_gy = new BigInteger(ecc_param[5], 16);  

        this.ecc_gx_fieldelement = new Fp(this.ecc_p, this.ecc_gx);  

        this.ecc_gy_fieldelement = new Fp(this.ecc_p, this.ecc_gy);  

        this.ecc_curve = new ECCurve.Fp(this.ecc_p, this.ecc_a, this.ecc_b);  

        this.ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement, this.ecc_gy_fieldelement);  

        this.ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n);  

        ECKeyGenerationParameters ecc_ecgenparam;  

        ecc_ecgenparam = new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom());  

        this.ecc_key_pair_generator = new ECKeyPairGenerator();  

        this.ecc_key_pair_generator.init(ecc_ecgenparam);  

    }  

}

SM2Utils.java

import java.io.IOException;  

import java.math.BigInteger;  

import org.bouncycastle.crypto.AsymmetricCipherKeyPair;  

import org.bouncycastle.crypto.params.ECPrivateKeyParameters;  

import org.bouncycastle.crypto.params.ECPublicKeyParameters;  

import org.bouncycastle.math.ec.ECPoint; 

public class SM2Utils {

      //生成随機秘鑰對  

    public static void generateKeyPair(){  

        SM2 sm2 = SM2.Instance();  

        AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair();  

        ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate();  

        ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic();  

        BigInteger privateKey = ecpriv.getD();  

        ECPoint publicKey = ecpub.getQ();  

        System.out.println("公鑰: " + Util.byteToHex(publicKey.getEncoded()));  

        System.out.println("私鑰: " + Util.byteToHex(privateKey.toByteArray()));  

    }  

    //資料加密  

    public static String encrypt(byte[] publicKey, byte[] data) throws IOException  

    {  

        if (publicKey == null || publicKey.length == 0)  

        {  

            return null;  

        }  

        if (data == null || data.length == 0)  

        {  

            return null;  

        }  

        byte[] source = new byte[data.length];  

        System.arraycopy(data, 0, source, 0, data.length);  

        Cipher cipher = new Cipher();  

        SM2 sm2 = SM2.Instance();  

        ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey);  

        ECPoint c1 = cipher.Init_enc(sm2, userKey);  

        cipher.Encrypt(source);  

        byte[] c3 = new byte[32];  

        cipher.Dofinal(c3);  

//      System.out.println("C1 " + Util.byteToHex(c1.getEncoded()));  

//      System.out.println("C2 " + Util.byteToHex(source));  

//      System.out.println("C3 " + Util.byteToHex(c3));  

        //C1 C2 C3拼裝成加密字串  

        return Util.byteToHex(c1.getEncoded()) + Util.byteToHex(source) + Util.byteToHex(c3);  

    }  

    //資料解密  

    public static byte[] decrypt(byte[] privateKey, byte[] encryptedData) throws IOException  

    {  

        if (privateKey == null || privateKey.length == 0)  

        {  

            return null;  

        }  

        if (encryptedData == null || encryptedData.length == 0)  

        {  

            return null;  

        }  

        //加密位元組數組轉換為十六進制的字元串 長度變為encryptedData.length * 2  

        String data = Util.byteToHex(encryptedData);  

        byte[] c1Bytes = Util.hexToByte(data.substring(0,130));  

        int c2Len = encryptedData.length - 97;  

        byte[] c2 = Util.hexToByte(data.substring(130,130 + 2 * c2Len));  

        byte[] c3 = Util.hexToByte(data.substring(130 + 2 * c2Len,194 + 2 * c2Len));  

        SM2 sm2 = SM2.Instance();  

        BigInteger userD = new BigInteger(1, privateKey);  

        //通過C1實體位元組來生成ECPoint  

        ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes);  

        Cipher cipher = new Cipher();  

        cipher.Init_dec(userD, c1);  

        cipher.Decrypt(c2);  

        cipher.Dofinal(c3);  

        //傳回解密結果  

        return c2;  

    }  

    public static void main(String[] args) throws Exception   

    {  

        //生成密鑰對  

        generateKeyPair();  

        String plainText = "ererfeiisgod";  

        byte[] sourceData = plainText.getBytes();  

        //下面的秘鑰可以使用generateKeyPair()生成的秘鑰内容  

        // 國密規範正式私鑰  

        String prik = "3690655E33D5EA3D9A4AE1A1ADD766FDEA045CDEAA43A9206FB8C430CEFE0D94";  

        // 國密規範正式公鑰  

        String pubk = "04F6E0C3345AE42B51E06BF50B98834988D54EBC7460FE135A48171BC0629EAE205EEDE253A530608178A98F1E19BB737302813BA39ED3FA3C51639D7A20C7391A";  

        System.out.println("加密: ");  

        String cipherText = SM2Utils.encrypt(Util.hexToByte(pubk), sourceData);  

        System.out.println(cipherText);  

        System.out.println("解密: ");  

        plainText = new String(SM2Utils.decrypt(Util.hexToByte(prik), Util.hexToByte(cipherText)));  

        System.out.println(plainText);  

    }  

}

SM3.java

public class SM3 {

     public static final byte[] iv = { 0x73, (byte) 0x80, 0x16, 0x6f, 0x49,  

                0x14, (byte) 0xb2, (byte) 0xb9, 0x17, 0x24, 0x42, (byte) 0xd7,  

                (byte) 0xda, (byte) 0x8a, 0x06, 0x00, (byte) 0xa9, 0x6f, 0x30,  

                (byte) 0xbc, (byte) 0x16, 0x31, 0x38, (byte) 0xaa, (byte) 0xe3,  

                (byte) 0x8d, (byte) 0xee, 0x4d, (byte) 0xb0, (byte) 0xfb, 0x0e,  

                0x4e };  

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

            static   

            {  

                for (int i = 0; i < 16; i++)   

                {  

                    Tj[i] = 0x79cc4519;  

                }  

                for (int i = 16; i < 64; i++)   

                {  

                    Tj[i] = 0x7a879d8a;  

                }  

            }  

            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 / 4];  

                byte[] tmp = new byte[4];  

                for (int i = 0; i < arr.length; i += 4)   

                {  

                    System.arraycopy(arr, i, tmp, 0, 4);  

                    out[i / 4] = bigEndianByteToInt(tmp);  

                }  

                return out;  

            }  

            private static byte[] convert(int[] arr)   

            {  

                byte[] out = new byte[arr.length * 4];  

                byte[] tmp = null;  

                for (int i = 0; i < arr.length; i++)   

                {  

                    tmp = bigEndianIntToByte(arr[i]);  

                    System.arraycopy(tmp, 0, out, i * 4, 4);  

                }  

                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[0];  

                b = V[1];  

                c = V[2];  

                d = V[3];  

                e = V[4];  

                f = V[5];  

                g = V[6];  

                h = V[7];  

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

                int[] w = arr[0];  

                int[] w1 = arr[1];  

                for (int j = 0; j < 64; j++)  

                {  

                    ss1 = (bitCycleLeft(a, 12) + e + bitCycleLeft(Tj[j], j));  

                    ss1 = bitCycleLeft(ss1, 7);  

                    ss2 = ss1 ^ bitCycleLeft(a, 12);  

                    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, 9);  

                    b = a;  

                    a = tt1;  

                    h = g;  

                    g = bitCycleLeft(f, 19);  

                    f = e;  

                    e = P0(tt2);  

                }  

//              System.out.println("");  

                int[] out = new int[8];  

                out[0] = a ^ V[0];  

                out[1] = b ^ V[1];  

                out[2] = c ^ V[2];  

                out[3] = d ^ V[3];  

                out[4] = e ^ V[4];  

                out[5] = f ^ V[5];  

                out[6] = g ^ V[6];  

                out[7] = h ^ V[7];  

                return out;  

            }  

            private static int[][] expand(int[] B)   

            {  

                int W[] = new int[68];  

                int W1[] = new int[64];  

                for (int i = 0; i < B.length; i++)  

                {  

                    W[i] = B[i];  

                }  

                for (int i = 16; i < 68; i++)   

                {  

                    W[i] = P1(W[i - 16] ^ W[i - 9] ^ bitCycleLeft(W[i - 3], 15))  

                            ^ bitCycleLeft(W[i - 13], 7) ^ W[i - 6];  

                }  

                for (int i = 0; i < 64; i++)   

                {  

                    W1[i] = W[i] ^ W[i + 4];  

                }  

                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 >= 0 && j <= 15)   

                {  

                    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 >= 0 && j <= 15)   

                {  

                    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, 9);  

                y = bitCycleLeft(X, 9);  

                int z = rotateLeft(X, 17);  

                z = bitCycleLeft(X, 17);  

                int t = X ^ y ^ z;  

                return t;  

            }  

            private static int P1(int X)   

            {  

                int t = X ^ bitCycleLeft(X, 15) ^ bitCycleLeft(X, 23);  

                return t;  

            }  

            public static byte[] padding(byte[] in, int bLen)  

            {  

                int k = 448 - (8 * in.length + 1) % 512;  

                if (k < 0)   

                {  

                    k = 960 - (8 * in.length + 1) % 512;  

                }  

                k += 1;  

                byte[] padd = new byte[k / 8];  

                padd[0] = (byte) 0x80;  

                long n = in.length * 8 + bLen * 512;  

                byte[] out = new byte[in.length + k / 8 + 64 / 8];  

                int pos = 0;  

                System.arraycopy(in, 0, out, 0, in.length);  

                pos += in.length;  

                System.arraycopy(padd, 0, out, pos, padd.length);  

                pos += padd.length;  

                byte[] tmp = back(Util.longToBytes(n));  

                System.arraycopy(tmp, 0, out, pos, tmp.length);  

                return out;  

            }  

            private static byte[] back(byte[] in)   

            {  

                byte[] out = new byte[in.length];  

                for (int i = 0; i < out.length; i++)   

                {  

                    out[i] = in[out.length - i - 1];  

                }  

                return out;  

            }  

            public static int rotateLeft(int x, int n)   

            {  

                return (x << n) | (x >> (32 - n));  

            }  

            private static int bitCycleLeft(int n, int bitLen)   

            {  

                bitLen %= 32;  

                byte[] tmp = bigEndianIntToByte(n);  

                int byteLen = bitLen / 8;  

                int len = bitLen % 8;  

                if (byteLen > 0)  

                {  

                    tmp = byteCycleLeft(tmp, byteLen);  

                }  

                if (len > 0)   

                {  

                    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 = 0; i < tmp.length; i++)  

                {  

                    t1 = (byte) ((in[i] & 0x000000ff) << len);  

                    t2 = (byte) ((in[(i + 1) % tmp.length] & 0x000000ff) >> (8 - 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, 0, in.length - byteLen);  

                System.arraycopy(in, 0, tmp, in.length - byteLen, byteLen);  

                return tmp;  

            }  

}

SM3Digest.java

import org.bouncycastle.util.encoders.Hex;  

public class SM3Digest {

    private static final int BYTE_LENGTH = 32;  

    private static final int BLOCK_LENGTH = 64;  

    private static final int BUFFER_LENGTH = BLOCK_LENGTH * 1;  

    private byte[] xBuf = new byte[BUFFER_LENGTH];  

    private int xBufOff;  

    private byte[] V = SM3.iv.clone();  

    private int cntBlock = 0;  

    public SM3Digest() {  

    }  

    public SM3Digest(SM3Digest t)  

    {  

        System.arraycopy(t.xBuf, 0, this.xBuf, 0, t.xBuf.length);  

        this.xBufOff = t.xBufOff;  

        System.arraycopy(t.V, 0, this.V, 0, t.V.length);  

    }  

    public int doFinal(byte[] out, int outOff)   

    {  

        byte[] tmp = doFinal();  

        System.arraycopy(tmp, 0, out, 0, tmp.length);  

        return BYTE_LENGTH;  

    }  

    public void reset()   

    {  

        xBufOff = 0;  

        cntBlock = 0;  

        V = SM3.iv.clone();  

    }  

    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, 0, 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 = 0; i < BUFFER_LENGTH; i += BLOCK_LENGTH)   

        {  

            System.arraycopy(xBuf, i, B, 0, B.length);  

            doHash(B);  

        }  

        xBufOff = 0;  

    }  

    private void doHash(byte[] B)  

    {  

        byte[] tmp = SM3.CF(V, B);  

        System.arraycopy(tmp, 0, V, 0, V.length);  

        cntBlock++;  

    }  

    private byte[] doFinal()   

    {  

        byte[] B = new byte[BLOCK_LENGTH];  

        byte[] buffer = new byte[xBufOff];  

        System.arraycopy(xBuf, 0, buffer, 0, buffer.length);  

        byte[] tmp = SM3.padding(buffer, cntBlock);  

        for (int i = 0; i < tmp.length; i += BLOCK_LENGTH)  

        {  

            System.arraycopy(tmp, i, B, 0, B.length);  

            doHash(B);  

        }  

        return V;  

    }  

    public void update(byte in)   

    {  

        byte[] buffer = new byte[] { in };  

        update(buffer, 0, 1);  

    }  

    public int getDigestSize()   

    {  

        return BYTE_LENGTH;  

    }  

    public static void main(String[] args)   

    {  

        byte[] md = new byte[32];  

        byte[] msg1 = "ererfeiisgod".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(s.toUpperCase());  

    }  

}

SM4_Context.java

public class SM4_Context {

    public int mode;  

    public long[] sk;  

    public boolean isPadding;  

    public SM4_Context()   

    {  

        this.mode = 1;  

        this.isPadding = true;  

        this.sk = new long[32];  

    }  

}

SM4.java

import java.io.ByteArrayInputStream;  

import java.io.ByteArrayOutputStream;  

public class SM4 {

     public static final int SM4_ENCRYPT = 1;  

    public static final int SM4_DECRYPT = 0;  

        private long GET_ULONG_BE(byte[] b, int i)   

        {  

            long n = (long)(b[i] & 0xff) << 24 | (long)((b[i + 1] & 0xff) << 16) | (long)((b[i + 2] & 0xff) << 8) | (long)(b[i + 3] & 0xff) & 0xffffffffL;  

            return n;  

        }  

        private void PUT_ULONG_BE(long n, byte[] b, int i)   

        {  

            b[i] = (byte)(int)(0xFF & n >> 24);  

            b[i + 1] = (byte)(int)(0xFF & n >> 16);  

            b[i + 2] = (byte)(int)(0xFF & n >> 8);  

            b[i + 3] = (byte)(int)(0xFF & n);  

        }  

        private long SHL(long x, int n)   

        {  

            return (x & 0xFFFFFFFF) << n;  

        }  

        private long ROTL(long x, int n)   

        {  

            return SHL(x, n) | x >> (32 - n);  

        }  

        private void SWAP(long[] sk, int i)  

        {  

            long t = sk[i];  

            sk[i] = sk[(31 - i)];  

            sk[(31 - i)] = t;  

        }  

        public static final byte[] SboxTable = { (byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe,  

            (byte) 0xcc, (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6,  

            0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b, 0x67,  

            (byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3,  

            (byte) 0xaa, 0x44, 0x13, 0x26, 0x49, (byte) 0x86, 0x06,  

            (byte) 0x99, (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91,  

            (byte) 0xef, (byte) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43,  

            (byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62, (byte) 0xe4,  

            (byte) 0xb3, 0x1c, (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8,  

            (byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94, (byte) 0xfa,  

            0x75, (byte) 0x8f, 0x3f, (byte) 0xa6, 0x47, 0x07, (byte) 0xa7,  

            (byte) 0xfc, (byte) 0xf3, 0x73, 0x17, (byte) 0xba, (byte) 0x83,  

            0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8,  

            0x68, 0x6b, (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda,  

            (byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70, 0x56,  

            (byte) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1,  

            (byte) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (byte) 0x87,  

            (byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27,  

            0x52, 0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4,  

            (byte) 0xc8, (byte) 0x9e, (byte) 0xea, (byte) 0xbf, (byte) 0x8a,  

            (byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3,  

            (byte) 0xf7, (byte) 0xf2, (byte) 0xce, (byte) 0xf9, 0x61, 0x15,  

            (byte) 0xa1, (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4,  

            (byte) 0x9b, 0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32,  

            0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3, 0x1d,  

            (byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca,  

            0x60, (byte) 0xc0, 0x29, 0x23, (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f,  

            (byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd,  

            (byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b,  

            0x51, (byte) 0x8d, 0x1b, (byte) 0xaf, (byte) 0x92, (byte) 0xbb,  

            (byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41,  

            0x1f, 0x10, 0x5a, (byte) 0xd8, 0x0a, (byte) 0xc1, 0x31,  

            (byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d,  

            0x74, (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4,  

            (byte) 0xb0, (byte) 0x89, 0x69, (byte) 0x97, 0x4a, 0x0c,  

            (byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09,  

            (byte) 0xc5, 0x6e, (byte) 0xc6, (byte) 0x84, 0x18, (byte) 0xf0,  

            0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79,  

            (byte) 0xee, 0x5f, 0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48 };  

        public static final int[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc };  

        public static final int[] CK = { 0x00070e15,0x1c232a31,0x383f464d,0x545b6269,  

            0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,  

            0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,  

            0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,  

            0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,  

            0x30373e45,0x4c535a61,0x686f767d,0x848b9299,  

            0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,  

            0x10171e25,0x2c333a41,0x484f565d,0x646b7279 };  

        private byte sm4Sbox(byte inch)  

        {  

            int i = inch & 0xFF;  

            byte retVal = SboxTable[i];  

            return retVal;  

        }  

        private long sm4Lt(long ka)   

        {  

            long bb = 0L;  

            long c = 0L;  

            byte[] a = new byte[4];  

            byte[] b = new byte[4];  

            PUT_ULONG_BE(ka, a, 0);  

            b[0] = sm4Sbox(a[0]);  

            b[1] = sm4Sbox(a[1]);  

            b[2] = sm4Sbox(a[2]);  

            b[3] = sm4Sbox(a[3]);  

            bb = GET_ULONG_BE(b, 0);  

            c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24);  

            return c;  

        }  

        private long sm4F(long x0, long x1, long x2, long x3, long rk)  

        {  

            return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk);  

        }  

        private long sm4CalciRK(long ka)   

        {  

            long bb = 0L;  

            long rk = 0L;  

            byte[] a = new byte[4];  

            byte[] b = new byte[4];  

            PUT_ULONG_BE(ka, a, 0);  

            b[0] = sm4Sbox(a[0]);  

            b[1] = sm4Sbox(a[1]);  

            b[2] = sm4Sbox(a[2]);  

            b[3] = sm4Sbox(a[3]);  

            bb = GET_ULONG_BE(b, 0);  

            rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23);  

            return rk;  

        }  

        private void sm4_setkey(long[] SK, byte[] key)   

        {  

            long[] MK = new long[4];  

            long[] k = new long[36];  

            int i = 0;  

            MK[0] = GET_ULONG_BE(key, 0);  

            MK[1] = GET_ULONG_BE(key, 4);  

            MK[2] = GET_ULONG_BE(key, 8);  

            MK[3] = GET_ULONG_BE(key, 12);  

            k[0] = MK[0] ^ (long) FK[0];  

            k[1] = MK[1] ^ (long) FK[1];  

            k[2] = MK[2] ^ (long) FK[2];  

            k[3] = MK[3] ^ (long) FK[3];  

            for (; i < 32; i++)   

            {  

                k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long) CK[i]));  

                SK[i] = k[(i + 4)];  

            }  

        }  

        private void sm4_one_round(long[] sk, byte[] input, byte[] output)   

        {  

            int i = 0;  

            long[] ulbuf = new long[36];  

            ulbuf[0] = GET_ULONG_BE(input, 0);  

            ulbuf[1] = GET_ULONG_BE(input, 4);  

            ulbuf[2] = GET_ULONG_BE(input, 8);  

            ulbuf[3] = GET_ULONG_BE(input, 12);  

            while (i < 32)  

            {  

                ulbuf[(i + 4)] = sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]);  

                i++;  

            }  

            PUT_ULONG_BE(ulbuf[35], output, 0);  

            PUT_ULONG_BE(ulbuf[34], output, 4);  

            PUT_ULONG_BE(ulbuf[33], output, 8);  

            PUT_ULONG_BE(ulbuf[32], output, 12);  

        }  

        private byte[] padding(byte[] input, int mode)  

        {  

            if (input == null)   

            {  

                return null;  

            }  

            byte[] ret = (byte[]) null;  

            if (mode == SM4_ENCRYPT)   

            {  

                int p = 16 - input.length % 16;  

                ret = new byte[input.length + p];  

                System.arraycopy(input, 0, ret, 0, input.length);  

                for (int i = 0; i < p; i++)   

                {  

                    ret[input.length + i] = (byte) p;  

                }  

            }   

            else   

            {  

                int p = input[input.length - 1];  

                ret = new byte[input.length - p];  

                System.arraycopy(input, 0, ret, 0, input.length - p);  

            }  

            return ret;  

        }  

        public void sm4_setkey_enc(SM4_Context ctx, byte[] key) throws Exception  

        {  

            if (ctx == null)   

            {  

                throw new Exception("ctx is null!");  

            }  

            if (key == null || key.length != 16)   

            {  

                throw new Exception("key error!");  

            }  

            ctx.mode = SM4_ENCRYPT;  

            sm4_setkey(ctx.sk, key);  

        }  

        public void sm4_setkey_dec(SM4_Context ctx, byte[] key) throws Exception  

        {  

            if (ctx == null)   

            {  

                throw new Exception("ctx is null!");  

            }  

            if (key == null || key.length != 16)   

            {  

                throw new Exception("key error!");  

            }  

            int i = 0;  

            ctx.mode = SM4_DECRYPT;  

            sm4_setkey(ctx.sk, key);  

            for (i = 0; i < 16; i++)   

            {  

                SWAP(ctx.sk, i);  

            }  

        }  

        public byte[] sm4_crypt_ecb(SM4_Context ctx, byte[] input) throws Exception   

        {  

            if (input == null)   

            {  

                throw new Exception("input is null!");  

            }  

            if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT))   

            {  

                input = padding(input, SM4_ENCRYPT);  

            }  

            int length = input.length;  

            ByteArrayInputStream bins = new ByteArrayInputStream(input);  

            ByteArrayOutputStream bous = new ByteArrayOutputStream();  

            for(; length > 0; length -= 16)  

            {  

                byte[] in = new byte[16];  

                byte[] out = new byte[16];  

                bins.read(in);  

                sm4_one_round(ctx.sk, in, out);  

                bous.write(out);  

            }  

            byte[] output = bous.toByteArray();  

            if (ctx.isPadding && ctx.mode == SM4_DECRYPT)   

            {  

                output = padding(output, SM4_DECRYPT);  

            }  

            bins.close();  

            bous.close();  

            return output;  

        }  

        public byte[] sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input) throws Exception  

        {  

            if (iv == null || iv.length != 16)  

            {  

                throw new Exception("iv error!");  

            }  

            if (input == null)   

            {  

                throw new Exception("input is null!");  

            }  

            if (ctx.isPadding && ctx.mode == SM4_ENCRYPT)   

            {  

                input = padding(input, SM4_ENCRYPT);  

            }  

            int i = 0;  

            int length = input.length;  

            ByteArrayInputStream bins = new ByteArrayInputStream(input);  

            ByteArrayOutputStream bous = new ByteArrayOutputStream();  

            if (ctx.mode == SM4_ENCRYPT)   

            {  

                for(; length > 0; length -= 16)  

                {  

                    byte[] in = new byte[16];  

                    byte[] out = new byte[16];  

                    byte[] out1 = new byte[16];  

                    bins.read(in);  

                    for (i = 0; i < 16; i++)   

                    {  

                        out[i] = ((byte) (in[i] ^ iv[i]));  

                    }  

                    sm4_one_round(ctx.sk, out, out1);  

                    System.arraycopy(out1, 0, iv, 0, 16);  

                    bous.write(out1);  

                }  

            }   

            else   

            {  

                byte[] temp = new byte[16];  

                for(; length > 0; length -= 16)  

                {  

                    byte[] in = new byte[16];  

                    byte[] out = new byte[16];  

                    byte[] out1 = new byte[16];  

                    bins.read(in);  

                    System.arraycopy(in, 0, temp, 0, 16);  

                    sm4_one_round(ctx.sk, in, out);  

                    for (i = 0; i < 16; i++)   

                    {  

                        out1[i] = ((byte) (out[i] ^ iv[i]));  

                    }  

                    System.arraycopy(temp, 0, iv, 0, 16);  

                    bous.write(out1);  

                }  

            }  

            byte[] output = bous.toByteArray();  

            if (ctx.isPadding && ctx.mode == SM4_DECRYPT)   

            {  

                output = padding(output, SM4_DECRYPT);  

            }  

            bins.close();  

            bous.close();  

            return output;  

        }  

}

SM4Utils.java

import java.io.IOException;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

public class SM4Utils {

//    private String secretKey = "";  

//    private String iv = "";  

//    private boolean hexString = false;  

    public String secretKey = "";  

    private String iv = "";  

    public boolean hexString = false;  

    public SM4Utils()  

    {  

    }  

//      

//    public byte encryptData_ECB1(byte[] inputStream){

//        try   

//        {  

//            SM4_Context ctx = new SM4_Context();  

//            ctx.isPadding = true;  

//            ctx.mode = SM4.SM4_ENCRYPT;  

//              

//            byte[] keyBytes;  

//            if (hexString)  

//            {  

//                keyBytes = Util.hexStringToBytes(secretKey);  

//            }  

//            else  

//            {  

//                keyBytes = secretKey.getBytes();  

//            }  

//              

//            SM4 sm4 = new SM4();  

//            sm4.sm4_setkey_enc(ctx, keyBytes);   

//            String cipherText = new BASE64Encoder().encode(inputStream);  

//            if (cipherText != null && cipherText.trim().length() > 0)  

//            {  

//                Pattern p = Pattern.compile("\\s*|\t|\r|\n");  

//                Matcher m = p.matcher(cipherText);  

//                cipherText = m.replaceAll("");  

//            }  

//            return cipherText;  

//        }   

//        catch (Exception e)   

//        {  

//            e.printStackTrace();  

//            return (Byte) null;  

//        }  

//    }

    public String encryptData_ECB(String plainText)  

    {  

        try   

        {  

            SM4_Context ctx = new SM4_Context();  

            ctx.isPadding = true;  

            ctx.mode = SM4.SM4_ENCRYPT;  

            byte[] keyBytes;  

            if (hexString)  

            {  

                keyBytes = Util.hexStringToBytes(secretKey);  

            }  

            else  

            {  

                keyBytes = secretKey.getBytes();  

            }  

            SM4 sm4 = new SM4();  

            sm4.sm4_setkey_enc(ctx, keyBytes);  

            byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainText.getBytes("GBK"));  

            String cipherText = new BASE64Encoder().encode(encrypted);  

            if (cipherText != null && cipherText.trim().length() > 0)  

            {  

                Pattern p = Pattern.compile("\\s*|\t|\r|\n");  

                Matcher m = p.matcher(cipherText);  

                cipherText = m.replaceAll("");  

            }  

            return cipherText;  

        }   

        catch (Exception e)   

        {  

            e.printStackTrace();  

            return null;  

        }  

    }  

    public String decryptData_ECB(String cipherText)  

    {  

        try   

        {  

            SM4_Context ctx = new SM4_Context();  

            ctx.isPadding = true;  

            ctx.mode = SM4.SM4_DECRYPT;  

            byte[] keyBytes;  

            if (hexString)  

            {  

                keyBytes = Util.hexStringToBytes(secretKey);  

            }  

            else  

            {  

                keyBytes = secretKey.getBytes();  

            }  

            SM4 sm4 = new SM4();  

            sm4.sm4_setkey_dec(ctx, keyBytes);  

            byte[] decrypted = sm4.sm4_crypt_ecb(ctx, new BASE64Decoder().decodeBuffer(cipherText));  

            return new String(decrypted, "GBK");  

        }   

        catch (Exception e)   

        {  

            e.printStackTrace();  

            return null;  

        }  

    }  

    public String encryptData_CBC(String plainText)  

    {  

        try   

        {  

            SM4_Context ctx = new SM4_Context();  

            ctx.isPadding = true;  

            ctx.mode = SM4.SM4_ENCRYPT;  

            byte[] keyBytes;  

            byte[] ivBytes;  

            if (hexString)  

            {  

                keyBytes = Util.hexStringToBytes(secretKey);  

                ivBytes = Util.hexStringToBytes(iv);  

            }  

            else  

            {  

                keyBytes = secretKey.getBytes();  

                ivBytes = iv.getBytes();  

            }  

            SM4 sm4 = new SM4();  

            sm4.sm4_setkey_enc(ctx, keyBytes);  

            byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainText.getBytes("GBK"));  

            String cipherText = new BASE64Encoder().encode(encrypted);  

            if (cipherText != null && cipherText.trim().length() > 0)  

            {  

                Pattern p = Pattern.compile("\\s*|\t|\r|\n");  

                Matcher m = p.matcher(cipherText);  

                cipherText = m.replaceAll("");  

            }  

            return cipherText;  

        }   

        catch (Exception e)   

        {  

            e.printStackTrace();  

            return null;  

        }  

    }  

    public String decryptData_CBC(String cipherText)  

    {  

        try   

        {  

            SM4_Context ctx = new SM4_Context();  

            ctx.isPadding = true;  

            ctx.mode = SM4.SM4_DECRYPT;  

            byte[] keyBytes;  

            byte[] ivBytes;  

            if (hexString)  

            {  

                keyBytes = Util.hexStringToBytes(secretKey);  

                ivBytes = Util.hexStringToBytes(iv);  

            }  

            else  

            {  

                keyBytes = secretKey.getBytes();  

                ivBytes = iv.getBytes();  

            }  

            SM4 sm4 = new SM4();  

            sm4.sm4_setkey_dec(ctx, keyBytes);  

            byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, new BASE64Decoder().decodeBuffer(cipherText));  

            return new String(decrypted, "GBK");  

        }   

        catch (Exception e)  

        {  

            e.printStackTrace();  

            return null;  

        }  

    }  

    public static void main(String[] args) throws IOException   

    {  

        String plainText = "ererfeiisgod";  

        SM4Utils sm4 = new SM4Utils();  

        sm4.secretKey = "JeF8U9wHFOMfs2Y8";  

        sm4.hexString = false;  

        System.out.println("ECB模式加密");  

        String cipherText = sm4.encryptData_ECB(plainText);  

        System.out.println("密文: " + cipherText);  

        System.out.println("");  

        plainText = sm4.decryptData_ECB(cipherText);  

        System.out.println("明文: " + plainText);  

        System.out.println("");  

        System.out.println("CBC模式加密");  

        sm4.iv = "UISwD9fW6cFh9SNS";  

        cipherText = sm4.encryptData_CBC(plainText);  

        System.out.println("密文: " + cipherText);  

        System.out.println("");  

        plainText = sm4.decryptData_CBC(cipherText);  

        System.out.println("明文: " + plainText);  

        System.out.println("CBC模式解密"); 

        System.out.println("密文:4esGgDn/snKraRDe6uM0jQ==");

        String cipherText2 = "4esGgDn/snKraRDe6uM0jQ==";

        plainText = sm4.decryptData_CBC(cipherText2);

        System.out.println("明文: " + plainText);  

    }  

}

Utils.java

import java.math.BigInteger; 

public class Util {

    public static byte[] intToBytes(int num)  

    {  

        byte[] bytes = new byte[4];  

        bytes[0] = (byte) (0xff & (num >> 0));  

        bytes[1] = (byte) (0xff & (num >> 8));  

        bytes[2] = (byte) (0xff & (num >> 16));  

        bytes[3] = (byte) (0xff & (num >> 24));  

        return bytes;  

    }  

    public static int byteToInt(byte[] bytes)   

    {  

        int num = 0;  

        int temp;  

        temp = (0x000000ff & (bytes[0])) << 0;  

        num = num | temp;  

        temp = (0x000000ff & (bytes[1])) << 8;  

        num = num | temp;  

        temp = (0x000000ff & (bytes[2])) << 16;  

        num = num | temp;  

        temp = (0x000000ff & (bytes[3])) << 24;  

        num = num | temp;  

        return num;  

    }  

    public static byte[] longToBytes(long num)   

    {  

        byte[] bytes = new byte[8];  

        for (int i = 0; i < 8; i++)   

        {  

            bytes[i] = (byte) (0xff & (num >> (i * 8)));  

        }  

        return bytes;  

    }  

    public static byte[] byteConvert32Bytes(BigInteger n)   

    {  

        byte tmpd[] = (byte[])null;  

        if(n == null)  

        {  

            return null;  

        }  

        if(n.toByteArray().length == 33)  

        {  

            tmpd = new byte[32];  

            System.arraycopy(n.toByteArray(), 1, tmpd, 0, 32);  

        }   

        else if(n.toByteArray().length == 32)  

        {  

            tmpd = n.toByteArray();  

        }   

        else  

        {  

            tmpd = new byte[32];  

            for(int i = 0; i < 32 - n.toByteArray().length; i++)  

            {  

                tmpd[i] = 0;  

            }  

            System.arraycopy(n.toByteArray(), 0, tmpd, 32 - n.toByteArray().length, n.toByteArray().length);  

        }  

        return tmpd;  

    }  

    public static BigInteger byteConvertInteger(byte[] b)  

    {  

        if (b[0] < 0)  

        {  

            byte[] temp = new byte[b.length + 1];  

            temp[0] = 0;  

            System.arraycopy(b, 0, temp, 1, b.length);  

            return new BigInteger(temp);  

        }  

        return new BigInteger(b);  

    }  

    public static String getHexString(byte[] bytes)   

    {  

        return getHexString(bytes, true);  

    }  

    public static String getHexString(byte[] bytes, boolean upperCase)   

    {  

        String ret = "";  

        for (int i = 0; i < bytes.length; i++)   

        {  

            ret += Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1);  

        }  

        return upperCase ? ret.toUpperCase() : ret;  

    }  

    public static void printHexString(byte[] bytes)   

    {  

        for (int i = 0; i < bytes.length; i++)   

        {  

            String hex = Integer.toHexString(bytes[i] & 0xFF);  

            if (hex.length() == 1)   

            {  

                hex = '0' + hex;  

            }  

            System.out.print("0x" + hex.toUpperCase() + ",");  

        }  

        System.out.println("");  

    }  

    public static byte[] hexStringToBytes(String hexString)   

    {  

        if (hexString == null || hexString.equals(""))   

        {  

            return null;  

        }  

        hexString = hexString.toUpperCase();  

        int length = hexString.length() / 2;  

        char[] hexChars = hexString.toCharArray();  

        byte[] d = new byte[length];  

        for (int i = 0; i < length; i++)   

        {  

            int pos = i * 2;  

            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));  

        }  

        return d;  

    }  

    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'};  

    public static char[] encodeHex(byte[] data) {  

        return encodeHex(data, true);  

    }  

    public static char[] encodeHex(byte[] data, boolean toLowerCase) {  

        return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);  

    }  

    protected static char[] encodeHex(byte[] data, char[] toDigits) {  

        int l = data.length;  

        char[] out = new char[l << 1];  

        // two characters form the hex value.  

        for (int i = 0, j = 0; i < l; i++) {  

            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];  

            out[j++] = toDigits[0x0F & data[i]];  

        }  

        return out;  

    }  

    public static String encodeHexString(byte[] data) {  

        return encodeHexString(data, true);  

    }  

    public static String encodeHexString(byte[] data, boolean toLowerCase) {  

        return encodeHexString(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);  

    }  

    protected static String encodeHexString(byte[] data, char[] toDigits) {  

        return new String(encodeHex(data, toDigits));  

    }  

    public static byte[] decodeHex(char[] data) {  

        int len = data.length;  

        if ((len & 0x01) != 0) {  

            throw new RuntimeException("Odd number of characters.");  

        }  

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

        // two characters form the hex value.  

        for (int i = 0, j = 0; j < len; i++) {  

            int f = toDigit(data[j], j) << 4;  

            j++;  

            f = f | toDigit(data[j], j);  

            j++;  

            out[i] = (byte) (f & 0xFF);  

        }  

        return out;  

    }  

    protected static int toDigit(char ch, int index) {  

        int digit = Character.digit(ch, 16);  

        if (digit == -1) {  

            throw new RuntimeException("Illegal hexadecimal character " + ch  

                    + " at index " + index);  

        }  

        return digit;  

    }  

    public static String StringToAsciiString(String content) {  

        String result = "";  

        int max = content.length();  

        for (int i = 0; i < max; i++) {  

            char c = content.charAt(i);  

            String b = Integer.toHexString(c);  

            result = result + b;  

        }  

        return result;  

    }  

    public static String hexStringToString(String hexString, int encodeType) {  

        String result = "";  

        int max = hexString.length() / encodeType;  

        for (int i = 0; i < max; i++) {  

            char c = (char) hexStringToAlgorism(hexString  

                    .substring(i * encodeType, (i + 1) * encodeType));  

            result += c;  

        }  

        return result;  

    }  

    public static int hexStringToAlgorism(String hex) {  

        hex = hex.toUpperCase();  

        int max = hex.length();  

        int result = 0;  

        for (int i = max; i > 0; i--) {  

            char c = hex.charAt(i - 1);  

            int algorism = 0;  

            if (c >= '0' && c <= '9') {  

                algorism = c - '0';  

            } else {  

                algorism = c - 55;  

            }  

            result += Math.pow(16, max - i) * algorism;  

        }  

        return result;  

    }  

    public static String hexStringToBinary(String hex) {  

        hex = hex.toUpperCase();  

        String result = "";  

        int max = hex.length();  

        for (int i = 0; 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;  

    }  

    public static String AsciiStringToString(String content) {  

        String result = "";  

        int length = content.length() / 2;  

        for (int i = 0; i < length; i++) {  

            String c = content.substring(i * 2, i * 2 + 2);  

            int a = hexStringToAlgorism(c);  

            char b = (char) a;  

            String d = String.valueOf(b);  

            result += d;  

        }  

        return result;  

    }  

    public static String algorismToHexString(int algorism, int maxLength) {  

        String result = "";  

        result = Integer.toHexString(algorism);  

        if (result.length() % 2 == 1) {  

            result = "0" + result;  

        }  

        return patchHexString(result.toUpperCase(), maxLength);  

    }  

    public static String byteToString(byte[] bytearray) {  

        String result = "";  

        char temp;  

        int length = bytearray.length;  

        for (int i = 0; i < length; i++) {  

            temp = (char) bytearray[i];  

            result += temp;  

        }  

        return result;  

    }  

    public static int binaryToAlgorism(String binary) {  

        int max = binary.length();  

        int result = 0;  

        for (int i = max; i > 0; i--) {  

            char c = binary.charAt(i - 1);  

            int algorism = c - '0';  

            result += Math.pow(2, max - i) * algorism;  

        }  

        return result;  

    }  

    public static String algorismToHEXString(int algorism) {  

        String result = "";  

        result = Integer.toHexString(algorism);  

        if (result.length() % 2 == 1) {  

            result = "0" + result;  

        }  

        result = result.toUpperCase();  

        return result;  

    }  

    static public String patchHexString(String str, int maxLength) {  

        String temp = "";  

        for (int i = 0; i < maxLength - str.length(); i++) {  

            temp = "0" + temp;  

        }  

        str = (temp + str).substring(0, maxLength);  

        return str;  

    }  

    public static int parseToInt(String s, int defaultInt, int radix) {  

        int i = 0;  

        try {  

            i = Integer.parseInt(s, radix);  

        } catch (NumberFormatException ex) {  

            i = defaultInt;  

        }  

        return i;  

    }  

    public static int parseToInt(String s, int defaultInt) {  

        int i = 0;  

        try {  

            i = Integer.parseInt(s);  

        } catch (NumberFormatException ex) {  

            i = defaultInt;  

        }  

        return i;  

    }  

    public static byte[] hexToByte(String hex)  

            throws IllegalArgumentException {  

        if (hex.length() % 2 != 0) {  

            throw new IllegalArgumentException();  

        }  

        char[] arr = hex.toCharArray();  

        byte[] b = new byte[hex.length() / 2];  

        for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {  

            String swap = "" + arr[i++] + arr[i];  

            int byteint = Integer.parseInt(swap, 16) & 0xFF;  

            b[j] = new Integer(byteint).byteValue();  

        }  

        return b;  

    }  

    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 = 0; n < b.length; n++) {  

            stmp = Integer.toHexString(b[n] & 0xff);  

            if (stmp.length() == 1) {  

                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 = 0; i < length; i++) {  

            bt[i] = input[i + startIndex];  

        }  

        return bt;  

    }  

}

————————————————

版權聲明:本文為CSDN部落客「Walter Sun」的原創文章,遵循 CC 4.0 BY-SA 版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/Soul_Programmer_Swh/article/details/80375958