pom

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>org.example</groupId>
  7. <artifactId>SM2test</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <dependencies>
  10. <dependency>
  11. <groupId>org.bouncycastle</groupId>
  12. <artifactId>bcprov-jdk15on</artifactId>
  13. <version>1.56</version>
  14. </dependency>
  15. </dependencies>
  16. </project>

Cipher

  1. import java.math.BigInteger;
  2. import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
  3. import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
  4. import org.bouncycastle.crypto.params.ECPublicKeyParameters;
  5. import org.bouncycastle.math.ec.ECPoint;
  6. public class Cipher {
  7. private int ct;
  8. private ECPoint p2;
  9. private SM3Digest sm3keybase;
  10. private SM3Digest sm3c3;
  11. private byte key[];
  12. private byte keyOff;
  13. public Cipher()
  14. {
  15. this.ct = 1;
  16. this.key = new byte[32];
  17. this.keyOff = 0;
  18. }
  19. private void Reset()
  20. {
  21. this.sm3keybase = new SM3Digest();
  22. this.sm3c3 = new SM3Digest();
  23. byte p[] = Util.byteConvert32Bytes(p2.getX().toBigInteger());
  24. this.sm3keybase.update(p, 0, p.length);
  25. this.sm3c3.update(p, 0, p.length);
  26. p = Util.byteConvert32Bytes(p2.getY().toBigInteger());
  27. this.sm3keybase.update(p, 0, p.length);
  28. this.ct = 1;
  29. NextKey();
  30. }
  31. private void NextKey()
  32. {
  33. SM3Digest sm3keycur = new SM3Digest(this.sm3keybase);
  34. sm3keycur.update((byte) (ct >> 24 & 0xff));
  35. sm3keycur.update((byte) (ct >> 16 & 0xff));
  36. sm3keycur.update((byte) (ct >> 8 & 0xff));
  37. sm3keycur.update((byte) (ct & 0xff));
  38. sm3keycur.doFinal(key, 0);
  39. this.keyOff = 0;
  40. this.ct++;
  41. }
  42. public ECPoint Init_enc(SM2 sm2, ECPoint userKey)
  43. {
  44. AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair();
  45. ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate();
  46. ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic();
  47. BigInteger k = ecpriv.getD();
  48. ECPoint c1 = ecpub.getQ();
  49. this.p2 = userKey.multiply(k);
  50. Reset();
  51. return c1;
  52. }
  53. public void Encrypt(byte data[])
  54. {
  55. this.sm3c3.update(data, 0, data.length);
  56. for (int i = 0; i < data.length; i++)
  57. {
  58. if (keyOff == key.length)
  59. {
  60. NextKey();
  61. }
  62. data[i] ^= key[keyOff++];
  63. }
  64. }
  65. public void Init_dec(BigInteger userD, ECPoint c1)
  66. {
  67. this.p2 = c1.multiply(userD);
  68. Reset();
  69. }
  70. public void Decrypt(byte data[])
  71. {
  72. for (int i = 0; i < data.length; i++)
  73. {
  74. if (keyOff == key.length)
  75. {
  76. NextKey();
  77. }
  78. data[i] ^= key[keyOff++];
  79. }
  80. this.sm3c3.update(data, 0, data.length);
  81. }
  82. public void Dofinal(byte c3[])
  83. {
  84. byte p[] = Util.byteConvert32Bytes(p2.getY().toBigInteger());
  85. this.sm3c3.update(p, 0, p.length);
  86. this.sm3c3.doFinal(c3, 0);
  87. Reset();
  88. }
  89. }

SM2

  1. import java.math.BigInteger;
  2. import java.security.SecureRandom;
  3. import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
  4. import org.bouncycastle.crypto.params.ECDomainParameters;
  5. import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
  6. import org.bouncycastle.math.ec.ECCurve;
  7. import org.bouncycastle.math.ec.ECFieldElement;
  8. import org.bouncycastle.math.ec.ECPoint;
  9. import org.bouncycastle.math.ec.ECFieldElement.Fp;
  10. public class SM2 {
  11. //正式参数
  12. public static String[] ecc_param = {
  13. "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",
  14. "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",
  15. "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",
  16. "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",
  17. "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",
  18. "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"
  19. };
  20. public static SM2 Instance() {
  21. return new SM2();
  22. }
  23. public final BigInteger ecc_p;
  24. public final BigInteger ecc_a;
  25. public final BigInteger ecc_b;
  26. public final BigInteger ecc_n;
  27. public final BigInteger ecc_gx;
  28. public final BigInteger ecc_gy;
  29. public final ECCurve ecc_curve;
  30. public final ECPoint ecc_point_g;
  31. public final ECDomainParameters ecc_bc_spec;
  32. public final ECKeyPairGenerator ecc_key_pair_generator;
  33. public final ECFieldElement ecc_gx_fieldelement;
  34. public final ECFieldElement ecc_gy_fieldelement;
  35. public SM2() {
  36. this.ecc_p = new BigInteger(ecc_param[0], 16);
  37. this.ecc_a = new BigInteger(ecc_param[1], 16);
  38. this.ecc_b = new BigInteger(ecc_param[2], 16);
  39. this.ecc_n = new BigInteger(ecc_param[3], 16);
  40. this.ecc_gx = new BigInteger(ecc_param[4], 16);
  41. this.ecc_gy = new BigInteger(ecc_param[5], 16);
  42. this.ecc_gx_fieldelement = new Fp(this.ecc_p, this.ecc_gx);
  43. this.ecc_gy_fieldelement = new Fp(this.ecc_p, this.ecc_gy);
  44. this.ecc_curve = new ECCurve.Fp(this.ecc_p, this.ecc_a, this.ecc_b);
  45. this.ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement, this.ecc_gy_fieldelement);
  46. this.ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n);
  47. ECKeyGenerationParameters ecc_ecgenparam;
  48. ecc_ecgenparam = new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom());
  49. this.ecc_key_pair_generator = new ECKeyPairGenerator();
  50. this.ecc_key_pair_generator.init(ecc_ecgenparam);
  51. }
  52. }

SM2KeyPair


  1. public class SM2KeyPair {
  2. /** 公钥 */
  3. private String publicKey;
  4. /** 私钥 */
  5. private String privateKey;
  6. SM2KeyPair(String publicKey, String privateKey) {
  7. this.publicKey = publicKey;
  8. this.privateKey = privateKey;
  9. }
  10. public String getPublicKey() {
  11. return publicKey;
  12. }
  13. public String getPrivateKey() {
  14. return privateKey;
  15. }
  16. }

SM2Utils

  1. import java.io.IOException;
  2. import java.math.BigInteger;
  3. import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
  4. import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
  5. import org.bouncycastle.crypto.params.ECPublicKeyParameters;
  6. import org.bouncycastle.math.ec.ECPoint;
  7. public class SM2Utils {
  8. //生成随机秘钥对
  9. public static SM2KeyPair generateKeyPair() {
  10. SM2 sm2 = SM2.Instance();
  11. AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair();
  12. ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate();
  13. ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic();
  14. BigInteger privateKey = ecpriv.getD();
  15. ECPoint publicKey = ecpub.getQ();
  16. System.out.println("公钥: " + Util.byteToHex(publicKey.getEncoded()));
  17. System.out.println("私钥: " + Util.byteToHex(privateKey.toByteArray()));
  18. return new SM2KeyPair(Util.byteToHex(publicKey.getEncoded(false)), Util.byteToHex(privateKey.toByteArray()));
  19. }
  20. //数据加密
  21. public static String encrypt(byte[] publicKey, byte[] data) throws IOException {
  22. if (publicKey == null || publicKey.length == 0) {
  23. return null;
  24. }
  25. if (data == null || data.length == 0) {
  26. return null;
  27. }
  28. byte[] source = new byte[data.length];
  29. System.arraycopy(data, 0, source, 0, data.length);
  30. Cipher cipher = new Cipher();
  31. SM2 sm2 = SM2.Instance();
  32. ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey);
  33. ECPoint c1 = cipher.Init_enc(sm2, userKey);
  34. cipher.Encrypt(source);
  35. byte[] c3 = new byte[32];
  36. cipher.Dofinal(c3);
  37. // System.out.println("C1 " + Util.byteToHex(c1.getEncoded()));
  38. // System.out.println("C2 " + Util.byteToHex(source));
  39. // System.out.println("C3 " + Util.byteToHex(c3));
  40. //C1 C2 C3拼装成加密字串
  41. return Util.byteToHex(c1.getEncoded(false)) + Util.byteToHex(source) + Util.byteToHex(c3);
  42. }
  43. //数据解密
  44. public static byte[] decrypt(byte[] privateKey, byte[] encryptedData) throws IOException {
  45. if (privateKey == null || privateKey.length == 0) {
  46. return null;
  47. }
  48. if (encryptedData == null || encryptedData.length == 0) {
  49. return null;
  50. }
  51. //加密字节数组转换为十六进制的字符串 长度变为encryptedData.length * 2
  52. String data = Util.byteToHex(encryptedData);
  53. /***分解加密字串
  54. * (C1 = C1标志位2位 + C1实体部分128位 = 130)
  55. * (C3 = C3实体部分64位 = 64)
  56. * (C2 = encryptedData.length * 2 - C1长度 - C2长度)
  57. */
  58. byte[] c1Bytes = Util.hexToByte(data.substring(0, 130));
  59. int c2Len = encryptedData.length - 97;
  60. byte[] c2 = Util.hexToByte(data.substring(130, 130 + 2 * c2Len));
  61. byte[] c3 = Util.hexToByte(data.substring(130 + 2 * c2Len, 194 + 2 * c2Len));
  62. SM2 sm2 = SM2.Instance();
  63. BigInteger userD = new BigInteger(1, privateKey);
  64. //通过C1实体字节来生成ECPoint
  65. ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes);
  66. Cipher cipher = new Cipher();
  67. cipher.Init_dec(userD, c1);
  68. cipher.Decrypt(c2);
  69. cipher.Dofinal(c3);
  70. //返回解密结果
  71. return c2;
  72. }
  73. public static void main(String[] args) throws Exception {
  74. //生成密钥对
  75. generateKeyPair();
  76. String plainText = "lxw测试!@#¥%……&*()";
  77. //下面的秘钥可以使用generateKeyPair()生成的秘钥内容
  78. // 国密规范正式私钥
  79. String prik = "7BF3DC32F3CCA2176CD8EA9267EE06E02E51378E7EA52CCEB42346BE70186804";
  80. // 国密规范正式公钥
  81. String pubk = "0497077E61FA0168D4EB00F475CAA21629D8BE5377311EAB2BB59D98B00970D0B9571935D8D4DB4DB8C24923FEBC3951088805EBF7989F16694CE57A903D24317B";
  82. System.out.println("-------加密: ");
  83. String cipherText = SM2Utils.encrypt(Util.hexStringToBytes(pubk), plainText.getBytes());
  84. System.out.println(cipherText);
  85. System.out.println("-------加密后字符串长度:" + cipherText.length());
  86. System.out.println("-------解密: ");
  87. byte[] decrypt = SM2Utils.decrypt(Util.hexStringToBytes(prik), Util.hexStringToBytes(cipherText));
  88. System.out.println(new String(decrypt));
  89. }
  90. }

SM3

  1. public class SM3 {
  2. public static final byte[] iv = { 0x73, (byte) 0x80, 0x16, 0x6f, 0x49,
  3. 0x14, (byte) 0xb2, (byte) 0xb9, 0x17, 0x24, 0x42, (byte) 0xd7,
  4. (byte) 0xda, (byte) 0x8a, 0x06, 0x00, (byte) 0xa9, 0x6f, 0x30,
  5. (byte) 0xbc, (byte) 0x16, 0x31, 0x38, (byte) 0xaa, (byte) 0xe3,
  6. (byte) 0x8d, (byte) 0xee, 0x4d, (byte) 0xb0, (byte) 0xfb, 0x0e,
  7. 0x4e };
  8. public static int[] Tj = new int[64];
  9. static
  10. {
  11. for (int i = 0; i < 16; i++)
  12. {
  13. Tj[i] = 0x79cc4519;
  14. }
  15. for (int i = 16; i < 64; i++)
  16. {
  17. Tj[i] = 0x7a879d8a;
  18. }
  19. }
  20. public static byte[] CF(byte[] V, byte[] B)
  21. {
  22. int[] v, b;
  23. v = convert(V);
  24. b = convert(B);
  25. return convert(CF(v, b));
  26. }
  27. private static int[] convert(byte[] arr)
  28. {
  29. int[] out = new int[arr.length / 4];
  30. byte[] tmp = new byte[4];
  31. for (int i = 0; i < arr.length; i += 4)
  32. {
  33. System.arraycopy(arr, i, tmp, 0, 4);
  34. out[i / 4] = bigEndianByteToInt(tmp);
  35. }
  36. return out;
  37. }
  38. private static byte[] convert(int[] arr)
  39. {
  40. byte[] out = new byte[arr.length * 4];
  41. byte[] tmp = null;
  42. for (int i = 0; i < arr.length; i++)
  43. {
  44. tmp = bigEndianIntToByte(arr[i]);
  45. System.arraycopy(tmp, 0, out, i * 4, 4);
  46. }
  47. return out;
  48. }
  49. public static int[] CF(int[] V, int[] B)
  50. {
  51. int a, b, c, d, e, f, g, h;
  52. int ss1, ss2, tt1, tt2;
  53. a = V[0];
  54. b = V[1];
  55. c = V[2];
  56. d = V[3];
  57. e = V[4];
  58. f = V[5];
  59. g = V[6];
  60. h = V[7];
  61. int[][] arr = expand(B);
  62. int[] w = arr[0];
  63. int[] w1 = arr[1];
  64. for (int j = 0; j < 64; j++)
  65. {
  66. ss1 = (bitCycleLeft(a, 12) + e + bitCycleLeft(Tj[j], j));
  67. ss1 = bitCycleLeft(ss1, 7);
  68. ss2 = ss1 ^ bitCycleLeft(a, 12);
  69. tt1 = FFj(a, b, c, j) + d + ss2 + w1[j];
  70. tt2 = GGj(e, f, g, j) + h + ss1 + w[j];
  71. d = c;
  72. c = bitCycleLeft(b, 9);
  73. b = a;
  74. a = tt1;
  75. h = g;
  76. g = bitCycleLeft(f, 19);
  77. f = e;
  78. e = P0(tt2);
  79. /*System.out.print(j+" ");
  80. System.out.print(Integer.toHexString(a)+" ");
  81. System.out.print(Integer.toHexString(b)+" ");
  82. System.out.print(Integer.toHexString(c)+" ");
  83. System.out.print(Integer.toHexString(d)+" ");
  84. System.out.print(Integer.toHexString(e)+" ");
  85. System.out.print(Integer.toHexString(f)+" ");
  86. System.out.print(Integer.toHexString(g)+" ");
  87. System.out.print(Integer.toHexString(h)+" ");
  88. System.out.println("");*/
  89. }
  90. // System.out.println("");
  91. int[] out = new int[8];
  92. out[0] = a ^ V[0];
  93. out[1] = b ^ V[1];
  94. out[2] = c ^ V[2];
  95. out[3] = d ^ V[3];
  96. out[4] = e ^ V[4];
  97. out[5] = f ^ V[5];
  98. out[6] = g ^ V[6];
  99. out[7] = h ^ V[7];
  100. return out;
  101. }
  102. private static int[][] expand(int[] B)
  103. {
  104. int W[] = new int[68];
  105. int W1[] = new int[64];
  106. for (int i = 0; i < B.length; i++)
  107. {
  108. W[i] = B[i];
  109. }
  110. for (int i = 16; i < 68; i++)
  111. {
  112. W[i] = P1(W[i - 16] ^ W[i - 9] ^ bitCycleLeft(W[i - 3], 15))
  113. ^ bitCycleLeft(W[i - 13], 7) ^ W[i - 6];
  114. }
  115. for (int i = 0; i < 64; i++)
  116. {
  117. W1[i] = W[i] ^ W[i + 4];
  118. }
  119. int arr[][] = new int[][] { W, W1 };
  120. return arr;
  121. }
  122. private static byte[] bigEndianIntToByte(int num)
  123. {
  124. return back(Util.intToBytes(num));
  125. }
  126. private static int bigEndianByteToInt(byte[] bytes)
  127. {
  128. return Util.byteToInt(back(bytes));
  129. }
  130. private static int FFj(int X, int Y, int Z, int j)
  131. {
  132. if (j >= 0 && j <= 15)
  133. {
  134. return FF1j(X, Y, Z);
  135. }
  136. else
  137. {
  138. return FF2j(X, Y, Z);
  139. }
  140. }
  141. private static int GGj(int X, int Y, int Z, int j)
  142. {
  143. if (j >= 0 && j <= 15)
  144. {
  145. return GG1j(X, Y, Z);
  146. }
  147. else
  148. {
  149. return GG2j(X, Y, Z);
  150. }
  151. }
  152. // 逻辑位运算函数
  153. private static int FF1j(int X, int Y, int Z)
  154. {
  155. int tmp = X ^ Y ^ Z;
  156. return tmp;
  157. }
  158. private static int FF2j(int X, int Y, int Z)
  159. {
  160. int tmp = ((X & Y) | (X & Z) | (Y & Z));
  161. return tmp;
  162. }
  163. private static int GG1j(int X, int Y, int Z)
  164. {
  165. int tmp = X ^ Y ^ Z;
  166. return tmp;
  167. }
  168. private static int GG2j(int X, int Y, int Z)
  169. {
  170. int tmp = (X & Y) | (~X & Z);
  171. return tmp;
  172. }
  173. private static int P0(int X)
  174. {
  175. int y = rotateLeft(X, 9);
  176. y = bitCycleLeft(X, 9);
  177. int z = rotateLeft(X, 17);
  178. z = bitCycleLeft(X, 17);
  179. int t = X ^ y ^ z;
  180. return t;
  181. }
  182. private static int P1(int X)
  183. {
  184. int t = X ^ bitCycleLeft(X, 15) ^ bitCycleLeft(X, 23);
  185. return t;
  186. }
  187. /**
  188. * 对最后一个分组字节数据padding
  189. *
  190. * @param in
  191. * @param bLen
  192. * 分组个数
  193. * @return
  194. */
  195. public static byte[] padding(byte[] in, int bLen)
  196. {
  197. int k = 448 - (8 * in.length + 1) % 512;
  198. if (k < 0)
  199. {
  200. k = 960 - (8 * in.length + 1) % 512;
  201. }
  202. k += 1;
  203. byte[] padd = new byte[k / 8];
  204. padd[0] = (byte) 0x80;
  205. long n = in.length * 8 + bLen * 512;
  206. byte[] out = new byte[in.length + k / 8 + 64 / 8];
  207. int pos = 0;
  208. System.arraycopy(in, 0, out, 0, in.length);
  209. pos += in.length;
  210. System.arraycopy(padd, 0, out, pos, padd.length);
  211. pos += padd.length;
  212. byte[] tmp = back(Util.longToBytes(n));
  213. System.arraycopy(tmp, 0, out, pos, tmp.length);
  214. return out;
  215. }
  216. /**
  217. * 字节数组逆序
  218. *
  219. * @param in
  220. * @return
  221. */
  222. private static byte[] back(byte[] in)
  223. {
  224. byte[] out = new byte[in.length];
  225. for (int i = 0; i < out.length; i++)
  226. {
  227. out[i] = in[out.length - i - 1];
  228. }
  229. return out;
  230. }
  231. public static int rotateLeft(int x, int n)
  232. {
  233. return (x << n) | (x >> (32 - n));
  234. }
  235. private static int bitCycleLeft(int n, int bitLen)
  236. {
  237. bitLen %= 32;
  238. byte[] tmp = bigEndianIntToByte(n);
  239. int byteLen = bitLen / 8;
  240. int len = bitLen % 8;
  241. if (byteLen > 0)
  242. {
  243. tmp = byteCycleLeft(tmp, byteLen);
  244. }
  245. if (len > 0)
  246. {
  247. tmp = bitSmall8CycleLeft(tmp, len);
  248. }
  249. return bigEndianByteToInt(tmp);
  250. }
  251. private static byte[] bitSmall8CycleLeft(byte[] in, int len)
  252. {
  253. byte[] tmp = new byte[in.length];
  254. int t1, t2, t3;
  255. for (int i = 0; i < tmp.length; i++)
  256. {
  257. t1 = (byte) ((in[i] & 0x000000ff) << len);
  258. t2 = (byte) ((in[(i + 1) % tmp.length] & 0x000000ff) >> (8 - len));
  259. t3 = (byte) (t1 | t2);
  260. tmp[i] = (byte) t3;
  261. }
  262. return tmp;
  263. }
  264. private static byte[] byteCycleLeft(byte[] in, int byteLen)
  265. {
  266. byte[] tmp = new byte[in.length];
  267. System.arraycopy(in, byteLen, tmp, 0, in.length - byteLen);
  268. System.arraycopy(in, 0, tmp, in.length - byteLen, byteLen);
  269. return tmp;
  270. }
  271. }

SM3Digest

  1. import org.bouncycastle.util.encoders.Hex;
  2. public class SM3Digest {
  3. /** SM3值的长度 */
  4. private static final int BYTE_LENGTH = 32;
  5. /** SM3分组长度 */
  6. private static final int BLOCK_LENGTH = 64;
  7. /** 缓冲区长度 */
  8. private static final int BUFFER_LENGTH = BLOCK_LENGTH * 1;
  9. /** 缓冲区 */
  10. private byte[] xBuf = new byte[BUFFER_LENGTH];
  11. /** 缓冲区偏移量 */
  12. private int xBufOff;
  13. /** 初始向量 */
  14. private byte[] V = SM3.iv.clone();
  15. private int cntBlock = 0;
  16. public SM3Digest() {
  17. }
  18. public SM3Digest(SM3Digest t)
  19. {
  20. System.arraycopy(t.xBuf, 0, this.xBuf, 0, t.xBuf.length);
  21. this.xBufOff = t.xBufOff;
  22. System.arraycopy(t.V, 0, this.V, 0, t.V.length);
  23. }
  24. /**
  25. * SM3结果输出
  26. *
  27. * @param out 保存SM3结构的缓冲区
  28. * @param outOff 缓冲区偏移量
  29. * @return
  30. */
  31. public int doFinal(byte[] out, int outOff)
  32. {
  33. byte[] tmp = doFinal();
  34. System.arraycopy(tmp, 0, out, 0, tmp.length);
  35. return BYTE_LENGTH;
  36. }
  37. public void reset()
  38. {
  39. xBufOff = 0;
  40. cntBlock = 0;
  41. V = SM3.iv.clone();
  42. }
  43. /**
  44. * 明文输入
  45. *
  46. * @param in
  47. * 明文输入缓冲区
  48. * @param inOff
  49. * 缓冲区偏移量
  50. * @param len
  51. * 明文长度
  52. */
  53. public void update(byte[] in, int inOff, int len)
  54. {
  55. int partLen = BUFFER_LENGTH - xBufOff;
  56. int inputLen = len;
  57. int dPos = inOff;
  58. if (partLen < inputLen)
  59. {
  60. System.arraycopy(in, dPos, xBuf, xBufOff, partLen);
  61. inputLen -= partLen;
  62. dPos += partLen;
  63. doUpdate();
  64. while (inputLen > BUFFER_LENGTH)
  65. {
  66. System.arraycopy(in, dPos, xBuf, 0, BUFFER_LENGTH);
  67. inputLen -= BUFFER_LENGTH;
  68. dPos += BUFFER_LENGTH;
  69. doUpdate();
  70. }
  71. }
  72. System.arraycopy(in, dPos, xBuf, xBufOff, inputLen);
  73. xBufOff += inputLen;
  74. }
  75. private void doUpdate()
  76. {
  77. byte[] B = new byte[BLOCK_LENGTH];
  78. for (int i = 0; i < BUFFER_LENGTH; i += BLOCK_LENGTH)
  79. {
  80. System.arraycopy(xBuf, i, B, 0, B.length);
  81. doHash(B);
  82. }
  83. xBufOff = 0;
  84. }
  85. private void doHash(byte[] B)
  86. {
  87. byte[] tmp = SM3.CF(V, B);
  88. System.arraycopy(tmp, 0, V, 0, V.length);
  89. cntBlock++;
  90. }
  91. private byte[] doFinal()
  92. {
  93. byte[] B = new byte[BLOCK_LENGTH];
  94. byte[] buffer = new byte[xBufOff];
  95. System.arraycopy(xBuf, 0, buffer, 0, buffer.length);
  96. byte[] tmp = SM3.padding(buffer, cntBlock);
  97. for (int i = 0; i < tmp.length; i += BLOCK_LENGTH)
  98. {
  99. System.arraycopy(tmp, i, B, 0, B.length);
  100. doHash(B);
  101. }
  102. return V;
  103. }
  104. public void update(byte in)
  105. {
  106. byte[] buffer = new byte[] { in };
  107. update(buffer, 0, 1);
  108. }
  109. public int getDigestSize()
  110. {
  111. return BYTE_LENGTH;
  112. }
  113. public static void main(String[] args)
  114. {
  115. byte[] md = new byte[32];
  116. byte[] msg1 = "lxw 测试".getBytes();
  117. SM3Digest sm3 = new SM3Digest();
  118. sm3.update(msg1, 0, msg1.length);
  119. sm3.doFinal(md, 0);
  120. String s = new String(Hex.encode(md));
  121. System.out.println(s.toUpperCase());
  122. }
  123. }

Util

  1. import java.math.BigInteger;
  2. public class Util {
  3. /**
  4. * 整形转换成网络传输的字节流(字节数组)型数据
  5. *
  6. * @param num 一个整型数据
  7. * @return 4个字节的自己数组
  8. */
  9. public static byte[] intToBytes(int num)
  10. {
  11. byte[] bytes = new byte[4];
  12. bytes[0] = (byte) (0xff & (num >> 0));
  13. bytes[1] = (byte) (0xff & (num >> 8));
  14. bytes[2] = (byte) (0xff & (num >> 16));
  15. bytes[3] = (byte) (0xff & (num >> 24));
  16. return bytes;
  17. }
  18. /**
  19. * 四个字节的字节数据转换成一个整形数据
  20. *
  21. * @param bytes 4个字节的字节数组
  22. * @return 一个整型数据
  23. */
  24. public static int byteToInt(byte[] bytes)
  25. {
  26. int num = 0;
  27. int temp;
  28. temp = (0x000000ff & (bytes[0])) << 0;
  29. num = num | temp;
  30. temp = (0x000000ff & (bytes[1])) << 8;
  31. num = num | temp;
  32. temp = (0x000000ff & (bytes[2])) << 16;
  33. num = num | temp;
  34. temp = (0x000000ff & (bytes[3])) << 24;
  35. num = num | temp;
  36. return num;
  37. }
  38. /**
  39. * 长整形转换成网络传输的字节流(字节数组)型数据
  40. *
  41. * @param num 一个长整型数据
  42. * @return 4个字节的自己数组
  43. */
  44. public static byte[] longToBytes(long num)
  45. {
  46. byte[] bytes = new byte[8];
  47. for (int i = 0; i < 8; i++)
  48. {
  49. bytes[i] = (byte) (0xff & (num >> (i * 8)));
  50. }
  51. return bytes;
  52. }
  53. /**
  54. * 大数字转换字节流(字节数组)型数据
  55. *
  56. * @param n
  57. * @return
  58. */
  59. public static byte[] byteConvert32Bytes(BigInteger n)
  60. {
  61. byte tmpd[] = (byte[])null;
  62. if(n == null)
  63. {
  64. return null;
  65. }
  66. if(n.toByteArray().length == 33)
  67. {
  68. tmpd = new byte[32];
  69. System.arraycopy(n.toByteArray(), 1, tmpd, 0, 32);
  70. }
  71. else if(n.toByteArray().length == 32)
  72. {
  73. tmpd = n.toByteArray();
  74. }
  75. else
  76. {
  77. tmpd = new byte[32];
  78. for(int i = 0; i < 32 - n.toByteArray().length; i++)
  79. {
  80. tmpd[i] = 0;
  81. }
  82. System.arraycopy(n.toByteArray(), 0, tmpd, 32 - n.toByteArray().length, n.toByteArray().length);
  83. }
  84. return tmpd;
  85. }
  86. /**
  87. * 换字节流(字节数组)型数据转大数字
  88. *
  89. * @param b
  90. * @return
  91. */
  92. public static BigInteger byteConvertInteger(byte[] b)
  93. {
  94. if (b[0] < 0)
  95. {
  96. byte[] temp = new byte[b.length + 1];
  97. temp[0] = 0;
  98. System.arraycopy(b, 0, temp, 1, b.length);
  99. return new BigInteger(temp);
  100. }
  101. return new BigInteger(b);
  102. }
  103. /**
  104. * 根据字节数组获得值(十六进制数字)
  105. *
  106. * @param bytes
  107. * @return
  108. */
  109. public static String getHexString(byte[] bytes)
  110. {
  111. return getHexString(bytes, true);
  112. }
  113. /**
  114. * 根据字节数组获得值(十六进制数字)
  115. *
  116. * @param bytes
  117. * @param upperCase
  118. * @return
  119. */
  120. public static String getHexString(byte[] bytes, boolean upperCase)
  121. {
  122. String ret = "";
  123. for (int i = 0; i < bytes.length; i++)
  124. {
  125. ret += Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1);
  126. }
  127. return upperCase ? ret.toUpperCase() : ret;
  128. }
  129. /**
  130. * 打印十六进制字符串
  131. *
  132. * @param bytes
  133. */
  134. public static void printHexString(byte[] bytes)
  135. {
  136. for (int i = 0; i < bytes.length; i++)
  137. {
  138. String hex = Integer.toHexString(bytes[i] & 0xFF);
  139. if (hex.length() == 1)
  140. {
  141. hex = '0' + hex;
  142. }
  143. System.out.print("0x" + hex.toUpperCase() + ",");
  144. }
  145. System.out.println("");
  146. }
  147. /**
  148. * Convert hex string to byte[]
  149. *
  150. * @param hexString
  151. * the hex string
  152. * @return byte[]
  153. */
  154. public static byte[] hexStringToBytes(String hexString)
  155. {
  156. if (hexString == null || hexString.equals(""))
  157. {
  158. return null;
  159. }
  160. hexString = hexString.toUpperCase();
  161. int length = hexString.length() / 2;
  162. char[] hexChars = hexString.toCharArray();
  163. byte[] d = new byte[length];
  164. for (int i = 0; i < length; i++)
  165. {
  166. int pos = i * 2;
  167. d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
  168. }
  169. return d;
  170. }
  171. /**
  172. * Convert char to byte
  173. *
  174. * @param c
  175. * char
  176. * @return byte
  177. */
  178. public static byte charToByte(char c)
  179. {
  180. return (byte) "0123456789ABCDEF".indexOf(c);
  181. }
  182. /**
  183. * 用于建立十六进制字符的输出的小写字符数组
  184. */
  185. private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5',
  186. '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  187. /**
  188. * 用于建立十六进制字符的输出的大写字符数组
  189. */
  190. private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5',
  191. '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  192. /**
  193. * 将字节数组转换为十六进制字符数组
  194. *
  195. * @param data byte[]
  196. * @return 十六进制char[]
  197. */
  198. public static char[] encodeHex(byte[] data) {
  199. return encodeHex(data, true);
  200. }
  201. /**
  202. * 将字节数组转换为十六进制字符数组
  203. *
  204. * @param data byte[]
  205. * @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
  206. * @return 十六进制char[]
  207. */
  208. public static char[] encodeHex(byte[] data, boolean toLowerCase) {
  209. return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
  210. }
  211. /**
  212. * 将字节数组转换为十六进制字符数组
  213. *
  214. * @param data byte[]
  215. * @param toDigits 用于控制输出的char[]
  216. * @return 十六进制char[]
  217. */
  218. protected static char[] encodeHex(byte[] data, char[] toDigits) {
  219. int l = data.length;
  220. char[] out = new char[l << 1];
  221. // two characters form the hex value.
  222. for (int i = 0, j = 0; i < l; i++) {
  223. out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
  224. out[j++] = toDigits[0x0F & data[i]];
  225. }
  226. return out;
  227. }
  228. /**
  229. * 将字节数组转换为十六进制字符串
  230. *
  231. * @param data byte[]
  232. * @return 十六进制String
  233. */
  234. public static String encodeHexString(byte[] data) {
  235. return encodeHexString(data, true);
  236. }
  237. /**
  238. * 将字节数组转换为十六进制字符串
  239. *
  240. * @param data byte[]
  241. * @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
  242. * @return 十六进制String
  243. */
  244. public static String encodeHexString(byte[] data, boolean toLowerCase) {
  245. return encodeHexString(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
  246. }
  247. /**
  248. * 将字节数组转换为十六进制字符串
  249. *
  250. * @param data byte[]
  251. * @param toDigits 用于控制输出的char[]
  252. * @return 十六进制String
  253. */
  254. protected static String encodeHexString(byte[] data, char[] toDigits) {
  255. return new String(encodeHex(data, toDigits));
  256. }
  257. /**
  258. * 将十六进制字符数组转换为字节数组
  259. *
  260. * @param data 十六进制char[]
  261. * @return byte[]
  262. * @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
  263. */
  264. public static byte[] decodeHex(char[] data) {
  265. int len = data.length;
  266. if ((len & 0x01) != 0) {
  267. throw new RuntimeException("Odd number of characters.");
  268. }
  269. byte[] out = new byte[len >> 1];
  270. // two characters form the hex value.
  271. for (int i = 0, j = 0; j < len; i++) {
  272. int f = toDigit(data[j], j) << 4;
  273. j++;
  274. f = f | toDigit(data[j], j);
  275. j++;
  276. out[i] = (byte) (f & 0xFF);
  277. }
  278. return out;
  279. }
  280. /**
  281. * 将十六进制字符转换成一个整数
  282. *
  283. * @param ch 十六进制char
  284. * @param index 十六进制字符在字符数组中的位置
  285. * @return 一个整数
  286. * @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
  287. */
  288. protected static int toDigit(char ch, int index) {
  289. int digit = Character.digit(ch, 16);
  290. if (digit == -1) {
  291. throw new RuntimeException("Illegal hexadecimal character " + ch
  292. + " at index " + index);
  293. }
  294. return digit;
  295. }
  296. /**
  297. * 数字字符串转ASCII码字符串
  298. *
  299. * @param content
  300. * 字符串
  301. * @return ASCII字符串
  302. */
  303. public static String StringToAsciiString(String content) {
  304. String result = "";
  305. int max = content.length();
  306. for (int i = 0; i < max; i++) {
  307. char c = content.charAt(i);
  308. String b = Integer.toHexString(c);
  309. result = result + b;
  310. }
  311. return result;
  312. }
  313. /**
  314. * 十六进制转字符串
  315. *
  316. * @param hexString
  317. * 十六进制字符串
  318. * @param encodeType
  319. * 编码类型4:Unicode,2:普通编码
  320. * @return 字符串
  321. */
  322. public static String hexStringToString(String hexString, int encodeType) {
  323. String result = "";
  324. int max = hexString.length() / encodeType;
  325. for (int i = 0; i < max; i++) {
  326. char c = (char) hexStringToAlgorism(hexString
  327. .substring(i * encodeType, (i + 1) * encodeType));
  328. result += c;
  329. }
  330. return result;
  331. }
  332. /**
  333. * 十六进制字符串装十进制
  334. *
  335. * @param hex
  336. * 十六进制字符串
  337. * @return 十进制数值
  338. */
  339. public static int hexStringToAlgorism(String hex) {
  340. hex = hex.toUpperCase();
  341. int max = hex.length();
  342. int result = 0;
  343. for (int i = max; i > 0; i--) {
  344. char c = hex.charAt(i - 1);
  345. int algorism = 0;
  346. if (c >= '0' && c <= '9') {
  347. algorism = c - '0';
  348. } else {
  349. algorism = c - 55;
  350. }
  351. result += Math.pow(16, max - i) * algorism;
  352. }
  353. return result;
  354. }
  355. /**
  356. * 十六转二进制
  357. *
  358. * @param hex
  359. * 十六进制字符串
  360. * @return 二进制字符串
  361. */
  362. public static String hexStringToBinary(String hex) {
  363. hex = hex.toUpperCase();
  364. String result = "";
  365. int max = hex.length();
  366. for (int i = 0; i < max; i++) {
  367. char c = hex.charAt(i);
  368. switch (c) {
  369. case '0':
  370. result += "0000";
  371. break;
  372. case '1':
  373. result += "0001";
  374. break;
  375. case '2':
  376. result += "0010";
  377. break;
  378. case '3':
  379. result += "0011";
  380. break;
  381. case '4':
  382. result += "0100";
  383. break;
  384. case '5':
  385. result += "0101";
  386. break;
  387. case '6':
  388. result += "0110";
  389. break;
  390. case '7':
  391. result += "0111";
  392. break;
  393. case '8':
  394. result += "1000";
  395. break;
  396. case '9':
  397. result += "1001";
  398. break;
  399. case 'A':
  400. result += "1010";
  401. break;
  402. case 'B':
  403. result += "1011";
  404. break;
  405. case 'C':
  406. result += "1100";
  407. break;
  408. case 'D':
  409. result += "1101";
  410. break;
  411. case 'E':
  412. result += "1110";
  413. break;
  414. case 'F':
  415. result += "1111";
  416. break;
  417. }
  418. }
  419. return result;
  420. }
  421. /**
  422. * ASCII码字符串转数字字符串
  423. *
  424. * @param content
  425. * ASCII字符串
  426. * @return 字符串
  427. */
  428. public static String AsciiStringToString(String content) {
  429. String result = "";
  430. int length = content.length() / 2;
  431. for (int i = 0; i < length; i++) {
  432. String c = content.substring(i * 2, i * 2 + 2);
  433. int a = hexStringToAlgorism(c);
  434. char b = (char) a;
  435. String d = String.valueOf(b);
  436. result += d;
  437. }
  438. return result;
  439. }
  440. /**
  441. * 将十进制转换为指定长度的十六进制字符串
  442. *
  443. * @param algorism
  444. * int 十进制数字
  445. * @param maxLength
  446. * int 转换后的十六进制字符串长度
  447. * @return String 转换后的十六进制字符串
  448. */
  449. public static String algorismToHexString(int algorism, int maxLength) {
  450. String result = "";
  451. result = Integer.toHexString(algorism);
  452. if (result.length() % 2 == 1) {
  453. result = "0" + result;
  454. }
  455. return patchHexString(result.toUpperCase(), maxLength);
  456. }
  457. /**
  458. * 字节数组转为普通字符串(ASCII对应的字符)
  459. *
  460. * @param bytearray
  461. * byte[]
  462. * @return String
  463. */
  464. public static String byteToString(byte[] bytearray) {
  465. String result = "";
  466. char temp;
  467. int length = bytearray.length;
  468. for (int i = 0; i < length; i++) {
  469. temp = (char) bytearray[i];
  470. result += temp;
  471. }
  472. return result;
  473. }
  474. /**
  475. * 二进制字符串转十进制
  476. *
  477. * @param binary
  478. * 二进制字符串
  479. * @return 十进制数值
  480. */
  481. public static int binaryToAlgorism(String binary) {
  482. int max = binary.length();
  483. int result = 0;
  484. for (int i = max; i > 0; i--) {
  485. char c = binary.charAt(i - 1);
  486. int algorism = c - '0';
  487. result += Math.pow(2, max - i) * algorism;
  488. }
  489. return result;
  490. }
  491. /**
  492. * 十进制转换为十六进制字符串
  493. *
  494. * @param algorism
  495. * int 十进制的数字
  496. * @return String 对应的十六进制字符串
  497. */
  498. public static String algorismToHEXString(int algorism) {
  499. String result = "";
  500. result = Integer.toHexString(algorism);
  501. if (result.length() % 2 == 1) {
  502. result = "0" + result;
  503. }
  504. result = result.toUpperCase();
  505. return result;
  506. }
  507. /**
  508. * HEX字符串前补0,主要用于长度位数不足。
  509. *
  510. * @param str
  511. * String 需要补充长度的十六进制字符串
  512. * @param maxLength
  513. * int 补充后十六进制字符串的长度
  514. * @return 补充结果
  515. */
  516. static public String patchHexString(String str, int maxLength) {
  517. String temp = "";
  518. for (int i = 0; i < maxLength - str.length(); i++) {
  519. temp = "0" + temp;
  520. }
  521. str = (temp + str).substring(0, maxLength);
  522. return str;
  523. }
  524. /**
  525. * 将一个字符串转换为int
  526. *
  527. * @param s
  528. * String 要转换的字符串
  529. * @param defaultInt
  530. * int 如果出现异常,默认返回的数字
  531. * @param radix
  532. * int 要转换的字符串是什么进制的,如16 8 10.
  533. * @return int 转换后的数字
  534. */
  535. public static int parseToInt(String s, int defaultInt, int radix) {
  536. int i = 0;
  537. try {
  538. i = Integer.parseInt(s, radix);
  539. } catch (NumberFormatException ex) {
  540. i = defaultInt;
  541. }
  542. return i;
  543. }
  544. /**
  545. * 将一个十进制形式的数字字符串转换为int
  546. *
  547. * @param s
  548. * String 要转换的字符串
  549. * @param defaultInt
  550. * int 如果出现异常,默认返回的数字
  551. * @return int 转换后的数字
  552. */
  553. public static int parseToInt(String s, int defaultInt) {
  554. int i = 0;
  555. try {
  556. i = Integer.parseInt(s);
  557. } catch (NumberFormatException ex) {
  558. i = defaultInt;
  559. }
  560. return i;
  561. }
  562. /**
  563. * 十六进制串转化为byte数组
  564. *
  565. * @return the array of byte
  566. */
  567. public static byte[] hexToByte(String hex)
  568. throws IllegalArgumentException {
  569. if (hex.length() % 2 != 0) {
  570. throw new IllegalArgumentException();
  571. }
  572. char[] arr = hex.toCharArray();
  573. byte[] b = new byte[hex.length() / 2];
  574. for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
  575. String swap = "" + arr[i++] + arr[i];
  576. int byteint = Integer.parseInt(swap, 16) & 0xFF;
  577. b[j] = new Integer(byteint).byteValue();
  578. }
  579. return b;
  580. }
  581. /**
  582. * 字节数组转换为十六进制字符串
  583. *
  584. * @param b
  585. * byte[] 需要转换的字节数组
  586. * @return String 十六进制字符串
  587. */
  588. public static String byteToHex(byte b[]) {
  589. if (b == null) {
  590. throw new IllegalArgumentException(
  591. "Argument b ( byte array ) is null! ");
  592. }
  593. String hs = "";
  594. String stmp = "";
  595. for (int n = 0; n < b.length; n++) {
  596. stmp = Integer.toHexString(b[n] & 0xff);
  597. if (stmp.length() == 1) {
  598. hs = hs + "0" + stmp;
  599. } else {
  600. hs = hs + stmp;
  601. }
  602. }
  603. return hs.toUpperCase();
  604. }
  605. public static byte[] subByte(byte[] input, int startIndex, int length) {
  606. byte[] bt = new byte[length];
  607. for (int i = 0; i < length; i++) {
  608. bt[i] = input[i + startIndex];
  609. }
  610. return bt;
  611. }
  612. }

附件下载

Java SM2的更多相关文章

  1. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  2. java 解析国密SM2算法证书

    首先说明用Java自带的解析x509证书类,是不能解析sm2算法的证书,执行会抛出异常. 用开源库bouncycastle能够解析.详细代码 private byte[] getCSPK(byte[] ...

  3. SM2的非对称加解密java工具类

    maven依赖 <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov- ...

  4. Java BC包做sm2加密方法 ,签名验签方法

    package com.sdyy.common.bc_sm2; import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateF ...

  5. JAVA 【SM2】加密解密

    JAVA [SM2]加密解密 前言:最近项目中必须用到SM2的加密解密 引入的Maven依赖 <dependency> <groupId>cn.hutool</group ...

  6. java解析密钥格式

    import java.io.StringReader; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1 ...

  7. 制作SM2证书

    前段时间将系统的RSA算法全部升级为SM2国密算法,密码机和UKey硬件设备大都同时支持RSA和SM2算法,只是应用系统的加解密签名验证需要修改,这个更改底层调用的加密动态库来,原来RSA用的对称加密 ...

  8. Java设计模式之《外观模式》及应用场景

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6484128.html 1.外观模式简介 外观模式,一般用在子系统与访问之间,用于对访问屏蔽复 ...

  9. bouncycastle 国密SM2 API的使用

    摘要:本文不对SM2做过多的介绍,主要介绍java bouncycastle库关于SM2的相关API的使用及注意事项 1. SM2 签名: 注意: 1)签名格式ASN1(描述了一种对数据进行表示.编码 ...

  10. java调用dll/so文件

    大家都知道用C++编写的程序如果用于windows使用则编译为xxx.dll文件,如果是Linux使用则编译为libxxx.so文件.下面将java调用dll/so文件的方法粘出来方便下次使用.此处使 ...

随机推荐

  1. Codeforces Round #824 (Div. 2) A-E

    比赛链接 A 题解 知识点:贪心,数学. 注意到三段工作时间一共 \(n-3\) 天,且天数实际上可以随意分配到任意一段,每段至少有一天,现在目的就是最大化段差最小值. 不妨设 \(l_1<l_ ...

  2. 数据抽取平台pydatax介绍

       缘起一:         公司现有数据仓库,是通过kettle从mysql抽取到目标库,运行多年,主要有以下问题, 1,效率低:kettle抽取行数少 2,容错性差:一个表抽取出错就导致后续计算 ...

  3. layui切换select选项事件

    说明 我们经常遇到表单上面选择不同的下拉选项需要触发函数去完成一些业务逻辑,比如我这个地方根据所选商品查询它底下明细的数量,并展示. 效果演示 代码 <!--选择商品--> <div ...

  4. python调用namp.py进行扫描,调用go编译的so文件

    #!/usr/bin/env python # -*- coding: utf-8 -*- import json import os import platform from ctypes impo ...

  5. 如何保证消息顺序执行(Rabbitmq/kafka)

    转载: https://www.cnblogs.com/-wenli/p/13047059.html https://www.jianshu.com/p/02fdcb9e8784

  6. 利用wiile双层循环打印各种星星---day06

    # 十行十列小星星 j = 0 #定义行数 while j<10: #当行数小于10的时候 i=0 #定义列 while i <10: #当列小于10的时候 print('*',end=' ...

  7. OFDM系统各种QAM调制阶数在多径信道下的误码性能仿真(暂存版本)

    本文考虑OFDM系统在多径信道下的误码性能 代码 clc;close all;clear %% Seting parameters EbN0_list = 20:2:40; Q_order_list ...

  8. Spring使用注解方式进行事务管理

    目录 使用步骤: 步骤一.在spring配置文件中引入tx:命名空间 步骤二.具有@Transactional 注解的bean自动配置为声明式事务支持 步骤三.在接口或类的声明处 ,写一个@Trans ...

  9. 【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误

    问题描述 PHP应用突然遇见了500 The page cannot be displayed because an internal server error has occurred.错误,但是如 ...

  10. 【Azure 存储服务】关于中国区Azure Storage Account 存储账号服务误删除后的恢复问题

    问题描述 在Azure上,如果需要恢复之前删除的存储账户(Storage Account), 有什么办法呢? 问题解答 Azure 现在推出了自主恢复已删除的存储账号的功能,具体步骤如下: 第一步: ...