1、简单介绍

这几天一直在看非对称的加密,相比之前的两篇内容,这次看了两倍多的时间还云里雾里的,所以这篇文章相对之前的两篇,概念性的东西多了些,另外是代码的每一步我都做了介绍,方便自己以后翻阅,也方便大家理解。最后就是关于代码的demo,DH算法、RSA算法本文中只有最基础的用法,实际在工作中可能会涉及到密钥的转换X509EncodedKeySpec和PKCS8EncodedKeySpec,相关的demo名分别叫DH2Test,RSA2Test,已经上传GIT。如果对您有帮助,请给我个star。本文为学习总结笔记,如有错误还请指正,谢谢W( ̄_ ̄)W

1.1 什么是非对称加密算法?

所谓非对称加密算法,即加密和解密使用两个不同的密钥。非对称主要是相对于对称加密算法而言的,对称加密算法有加解密使用同一个秘钥,非对称算法则有一个公钥和一个私钥,公钥与私钥是一对的,这两个共同组成一个解钥,才能实现解密。

Ps:RSA是可以双向加密的:私钥加密,公钥解密;公钥加密,私钥解密。

1.2 主要算法

DH 秘钥交换算法,算是非对称加密算法的起源

RSA 基于因子分解,既能用于数字加密也能用于数字签名

ELGamal 基于离散对数加密

1.3 非对称加密算法的特点

算法强度复杂、安全性依赖于算法与密钥.但是由于算法复杂,使得非对称算法加解密速度没有对称算法加解密的速度快.

对称密钥体制中只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥.所以保证其安全性就是保证密钥的安全.

非对称密钥体制有两种密钥,其中一个是公开的,这样就可以不需要像对称密码那样向对方传输密钥了.因此安全性就大了很多.

算法复杂度:对称密钥<非对称密钥

加解密速度:对称密钥>非对称密钥

安全性:对称密钥<非对称密钥

1.4 使用到的类和相关参数

KeyPairGenerator:密钥对生成器
KeyPair:密钥对
PublixKey:公钥
PrivateKey :私钥
KeyFactory:作用是生成密钥(包括公钥和私钥)

generatePublic()方法用来生成公钥
generatePrivate()方法用来生成私钥

X509EncodedKeySpec:继承EncodedKeySpec类 ,以编码格式来表示公钥
PKCS8EncodedKeySpec:继承EncodedKeySpec类,以编码格式来表示私钥
DHPublicKey:是PublicKey的某种具体的形式
DHParameterSpec:随从着DH算法来使用的参数的集合
KeyAgreement:该类提供密钥一致性(或者密钥交换)协议的功能
SecretKey:构建的本地秘钥
Cipher:提供加解密的功能

2、DH算法

Diffie-Hellman算法(D-H算法),密钥一致协议。是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。换句话说,就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥)。以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥(SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。不单单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯!该算法源于中国的同余定理——中国馀数定理。

DH算法的默认密钥长度是1024,密钥长度必须是64的倍数,在512到1024位之间。
DH是一种基于密钥一致协议的加密算法。

密钥一致协议就是允许两名用户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。

由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥),以此为基线作为数据传输保密基础.同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。在互通了本地密钥算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。

2.1 算法流程

1.甲方构建密钥对,将公钥公布给乙方,将私钥保留;双方约定数据加密算法;乙方通过甲方公钥构建密钥对,将公钥公布给甲方,将私钥保留。 
2.甲方使用私钥、乙方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥加密数据,发送给乙方加密后的数据;乙方使用私钥、甲方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥对数据解密。 
3.乙方使用私钥、甲方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥加密数据,发送给甲方加密后的数据;甲方使用私钥、乙方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥对数据解密。

2.2 具体实现

使用KeyPairGenerator的getInstance()静态方法创建实例,参数是算法名称.指定密钥对生成器生成指定算法的密钥对。

  1. KeyPairGenerator senderKeyPairGenerator =KeyPairGenerator.getInstance("DH");

使用KeyPairGenerator的initialize()方法初始化密钥的长度.

  1. senderKeyPairGenerator.initialize(512);

使用KeyPairGenerator的generateKeyPair()方法创建KeyPair实例.一个KeyPair实例表示一对密钥,即一个密钥对.包括公钥与私钥.

  1. KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();

KeyPair的getPublic()方法返回PublicKey类型(公钥),getPrivate()方法返回PrivateKey类型(私钥)。
DHPublicKey接口、DHPrivateKey接口分别继承PublicKey接口与PrivateKey接口.

公钥是要发送给接收方的,此处同一类内省略该操作

  1. PublicKey senderPublicKey = senderKeyPair.getPublic();//发送方公钥

使用DHPublicKey的getParams()方法返回DHParameterSpec实例.
DHParameterSpec:此类指定随同DH算法使用的参数集合,用于通过一方的公钥生成另一方的密钥对.

  1. DHParameterSpec dhParameterSpec = ((DHPublicKey) senderPublicKey).getParams();//用发送方的公钥产生算法参数

使用KeyPairGenerator的initialize()初始化方法时,参数还可以是DHParameterSpec的实例.用于通过一方公钥生成密钥对.

  1. KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
  2. receiverKeyPairGenerator.initialize(dhParameterSpec);//初始化接收方的KeyPairGenerator
  3. KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();//生成接收方的密钥对

本地密钥构建:KeyAgreement
KeyAgreement类用于生成本地密钥(提供密钥协定或密钥交换协议的功能).使用其getInstance()静态方法创建实例,参数是算法名,指定生成的本地密钥符合某种特定算法.

  1. KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");

KeyAgreement类的init()方法用于给定密钥初始化此密钥协定.doPhase()方法用于用给定密钥执行此密钥协定的下一个阶段.两个方法的参数都是Key类型,即使用公钥、私钥来初始化密钥协定.

  1. keyAgreement.init(receiverKeyPair.getPrivate());//接收方的私钥
  2. keyAgreement.doPhase(senderKeyPair.getPublic(), true);//发送方的公钥

KeyAgreement类的generateSecret()方法创建本地密钥,参数是对称加密算法名称.返回SecretKey类型.

  1. SecretKey receiverDesKey = keyAgreement.generateSecret("DES");

加密解密,同java加密算法入门(二)-对称加密详解 不在详细讲了

  1. Cipher cipher=Cipher.getInstance("DES"):
  2. cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);
  3. byte[] result = cipher.doFinal(src.getBytes());

2.3 实现代码

  1. package Asymmetric.encryption;
  2.  
  3. import org.apache.commons.codec.binary.Hex;
  4. import javax.crypto.Cipher;
  5. import javax.crypto.KeyAgreement;
  6. import javax.crypto.SecretKey;
  7. import javax.crypto.interfaces.DHPublicKey;
  8. import javax.crypto.spec.DHParameterSpec;
  9. import java.security.KeyPair;
  10. import java.security.KeyPairGenerator;
  11. import java.security.PublicKey;
  12. import java.util.Objects;
  13.  
  14. /**
  15. * {@link http://www.cnblogs.com/allanzhang/}
  16. * @author 小卖铺的老爷爷
  17. * DH 相当于外面的一层封装。进行密钥交换用的。并不是一种明确的加解密算法
  18. */
  19. public class DHTest {
  20. public static final String src = "laoyeye dh";
  21.  
  22. public static void main(String[] args) throws Exception {
  23. jdkDH();
  24. }
  25.  
  26. public static void jdkDH() throws Exception {
  27. //发送方初始化自己的密钥对,并且把公钥发送给接收方
  28. KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
  29. senderKeyPairGenerator.initialize(512);
  30. KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();
  31. PublicKey senderPublicKey = senderKeyPair.getPublic();//公钥是要发送给接收方的,此处同一类内省略该操作
  32.  
  33. //接收方用发送方的公钥初始化自己的密钥对
  34. DHParameterSpec dhParameterSpec = ((DHPublicKey) senderPublicKey).getParams();//用发送方的公钥产生算法参数
  35. KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
  36. receiverKeyPairGenerator.initialize(dhParameterSpec);//初始化接收方的KeyPairGenerator
  37. KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();//生产接收方的密钥对
  38.  
  39. //DES密钥构建
  40. KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
  41. //接收方根据自己的私钥和发送方的公钥创建DES密钥
  42. keyAgreement.init(receiverKeyPair.getPrivate());//接收方的私钥
  43. keyAgreement.doPhase(senderKeyPair.getPublic(), true);//发送方的公钥
  44. SecretKey receiverDesKey = keyAgreement.generateSecret("DES");
  45.  
  46. //发送方根据自己的私钥和接收方的公钥创建DES密钥
  47. keyAgreement.init(senderKeyPair.getPrivate());
  48. keyAgreement.doPhase(receiverKeyPair.getPublic(), true);
  49. SecretKey senderDesKey = keyAgreement.generateSecret("DES");
  50.  
  51. //判断两方得到的DES密钥是不是相等的
  52. if (Objects.equals(senderDesKey, receiverDesKey)) {
  53. System.out.println("双方密钥相同");
  54. }
  55.  
  56. //加密
  57. Cipher cipher = Cipher.getInstance("DES");
  58. cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);
  59. byte[] result = cipher.doFinal(src.getBytes());
  60. System.out.println("JDK DH ENCRYPT:" + Hex.encodeHexString(result));
  61.  
  62. //解密
  63. cipher.init(Cipher.DECRYPT_MODE, receiverDesKey);
  64. result = cipher.doFinal(result);
  65. System.out.println("JDK DH DECRYPT:" + new String(result));
  66.  
  67. }
  68.  
  69. }

3、RSA算法

这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。 
这种加密算法的特点主要是密钥的变化,java加密算法入门(二)-对称加密详解 一文中我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。

RSA算法的JDK实现默认密钥长度是1024,BC则是2048,密钥长度必须是64的倍数,在512到65536位之间。
RSA目前还没有被破解,是使用最多的非对称加密算法.
有些算法只规定了公钥加密、私钥解密,RSA算法则支持公钥加密、私钥解密.私钥加密、公钥解密。

3.1 算法流程

1.甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。
2.甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。
3.乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。
Ps:关于数字签名会在后续的章节中介绍。可以看看这个帖子了解下http://justjavac.iteye.com/blog/1144151

一般公司这样做的。
甲乙公司各有自己的一套公钥私钥。
甲用乙公布的公钥加密,信息传递到乙,乙用自己的私钥解密。 --- 这一套是乙方的公私钥。
乙用甲公布的公钥加密,信息传递到甲,甲用自己的私钥解密。 --- 这一套是甲方的公私钥。
注:公钥长度远远小于私钥,公钥长度比较短,便于公钥保存。

3.2 代码实现

  1. package Asymmetric.encryption;
  2.  
  3. import org.apache.commons.codec.binary.Hex;
  4. import javax.crypto.Cipher;
  5. import java.security.KeyPair;
  6. import java.security.KeyPairGenerator;
  7. /**
  8. * {@link http://www.cnblogs.com/allanzhang/}
  9. * @author 小卖铺的老爷爷
  10. *
  11. */
  12. public class RSATest {
  13. public static final String src = "laoyeye rsa";
  14. public static void main(String[] args) throws Exception {
  15. jdkRSA();
  16. }
  17. public static void jdkRSA() throws Exception {
  18. //初始化密钥
  19. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
  20. keyPairGenerator.initialize(512);//512~65532
  21. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  22. //私钥加密,公钥解密
  23. Cipher cipher = Cipher.getInstance("RSA");
  24. cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate());
  25. byte[] result = cipher.doFinal(src.getBytes());
  26. System.out.println("**私钥加密,公钥解密**");
  27. System.out.println("加密:" + Hex.encodeHexString(result));
  28. cipher.init(Cipher.DECRYPT_MODE, keyPair.getPublic());
  29. result = cipher.doFinal(result);
  30. System.out.println("解密:" + new String(result));
  31. }
  32. }

4、ElGamal算法

ElGamal算法,是一种较为常见的加密算法,它是基于1985年提出的公钥密码体制和椭圆曲线加密体系。既能用于数据加密也能用于数字签名,其安全性依赖于计算有限域上离散对数这一难题。在加密过程中,生成的密文长度是明文的两倍,且每次加密后都会在密文中生成一个随机数K,在密码中主要应用离散对数问题的几个性质:求解离散对数(可能)是困难的,而其逆运算指数运算可以应用平方-乘的方法有效地计算。也就是说,在适当的群G中,指数函数是单向函数。

特点:
1、在JDK里并没有提供对ElGamal算法的实现.而是通过BouncyCastle实现.
2、只提供公钥加密,私钥解密,不提供私钥加密,公钥解密
3、ElGamal算法支持数据加密与数字签名.
4、密钥长度:160~16384(8的倍数),默认的密钥长度为1024.

4.1 算法流程

1.乙方构建密钥对儿,将公钥公布给甲方,将私钥保留。
2.甲方使用公钥加密数据,然后用公钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用私钥、签名来验证待解密数据是否有效,如果有效使用私钥对数据解密。

4.2 具体步骤

在使用之前需要为JDK添加新的Provider.

  1. Security.addProvider(new BouncyCastleProvider());

RSA初始化密钥对是通过KeyPairGenerator实现的.而ElGamal初始化密钥对则是通过AlgorithmParameterGenerator实现的.
使用AlgorithmParameterGenerator的getInstance()静态方法获取AlgorithmParameterGenerator实例,参数是算法名.

  1. AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator.getInstance("Elgamal");

使用AlgorithmParameterGenerator的init()方法进行初始化密钥长度.

  1. algorithmParameterGenerator.init(256);

JDK没有提供对ElGamal的支持,但是jce提供了构建秘钥对的方式DHParameterSpec,具体方式见代码

  1. // 生成算法参数
  2. AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();
  3. // 构建参数材料
  4. //JDK没有提供对ei的支持,但是jce框架提供了构建秘钥对的方式DHParameterSpec
  5. DHParameterSpec dhParameterSpec = (DHParameterSpec)algorithmParameters.getParameterSpec(DHParameterSpec.class);
  6. // 实例化密钥对生成器
  7. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Elgamal");
  8. // 初始化密钥对生成器
  9. keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());
  10. KeyPair keyPair = keyPairGenerator.generateKeyPair();

到这一步后就和RSA的步骤类似了,可参考上文或者查看实现代码。

4.3 实现代码

  1. package Asymmetric.encryption;
  2.  
  3. import java.security.AlgorithmParameterGenerator;
  4. import java.security.AlgorithmParameters;
  5. import java.security.KeyFactory;
  6. import java.security.KeyPair;
  7. import java.security.KeyPairGenerator;
  8. import java.security.PrivateKey;
  9. import java.security.PublicKey;
  10. import java.security.SecureRandom;
  11. import java.security.Security;
  12. import java.security.spec.PKCS8EncodedKeySpec;
  13. import java.security.spec.X509EncodedKeySpec;
  14.  
  15. import javax.crypto.Cipher;
  16. import javax.crypto.spec.DHParameterSpec;
  17.  
  18. import org.apache.commons.codec.binary.Base64;
  19. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  20. /**
  21. * {@link http://www.cnblogs.com/allanzhang/}
  22. * @author 小卖铺的老爷爷
  23. *
  24. */
  25. public class ElGamalTest {
  26.  
  27. public static final String src = "laoyeye Elgamal test";
  28. public static void main(String[] args)
  29. {
  30. jdkElgamal();
  31.  
  32. }
  33. // jdk实现:“公钥加密,私钥解密” , 因为Elgamal不支持“私钥加密、公钥解密”。
  34. public static void jdkElgamal()
  35. {
  36. try
  37. {
  38. // 加入对BouncyCastle支持
  39. Security.addProvider(new BouncyCastleProvider());
  40.  
  41. // 初始化密钥
  42. AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator.getInstance("Elgamal");
  43. // 初始化参数生成器
  44. algorithmParameterGenerator.init(256);
  45. // 生成算法参数
  46. AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();
  47. // 构建参数材料
  48. //JDK没有提供对ei的支持,但是jce框架提供了构建秘钥对的方式DHParameterSpec
  49. DHParameterSpec dhParameterSpec = (DHParameterSpec)algorithmParameters.getParameterSpec(DHParameterSpec.class);
  50. // 实例化密钥对生成器
  51. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Elgamal");
  52. // 初始化密钥对生成器
  53. keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());
  54. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  55. // 公钥
  56. PublicKey elGamalPublicKey = keyPair.getPublic();
  57. // 私钥
  58. PrivateKey elGamalPrivateKey = keyPair.getPrivate();
  59. System.out.println("Public Key:" + Base64.encodeBase64String(elGamalPublicKey.getEncoded()));
  60. System.out.println("Private Key:" + Base64.encodeBase64String(elGamalPrivateKey.getEncoded()));
  61. // 初始化公钥
  62. // 密钥材料转换
  63. X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(elGamalPublicKey.getEncoded());
  64. // 实例化密钥工厂
  65. KeyFactory keyFactory = KeyFactory.getInstance("Elgamal");
  66. // 产生公钥
  67. PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec2);
  68. // 数据加密
  69. // Cipher cipher = Cipher.getInstance("Elgamal");
  70. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  71. cipher.init(Cipher.ENCRYPT_MODE, publicKey2);
  72. byte[] result2 = cipher.doFinal(src.getBytes());
  73. System.out.println("Elgamal ---- 加密:" + Base64.encodeBase64String(result2));
  74. // 数据解密
  75. PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded());
  76. keyFactory = KeyFactory.getInstance("Elgamal");
  77. PrivateKey privateKey5 = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
  78. // Cipher cipher5 = Cipher.getInstance("Elgamal");
  79. Cipher cipher5 = Cipher.getInstance(keyFactory.getAlgorithm());
  80. cipher5.init(Cipher.DECRYPT_MODE, privateKey5);
  81. byte[] result5 = cipher5.doFinal(result2);
  82. System.out.println("Elgamal ---- 解密:" + new String(result5));
  83. } catch (Exception e) {
  84. e.printStackTrace();
  85. }
  86.  
  87. }
  88.  
  89. }

4.4 遇到的问题

代码报错:“Illegal key size or default parameters”异常,是因为美国的出口限制,Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制。因此存在一些问题。

Java 6 无政策限制文件:http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
Java 7 无政策限制文件:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
找到对应jdk的安装目录。D:\JDK1.6\jdk1.7.0_45\jre\lib\security目录下,对应覆盖local_policy.jar和US_export_policy.jar两个jar包就可以了。

补充:
关于源码中PKCS8EncodedKeySpec,X509EncodedKeySpec密钥的转换,实际上并不需要转换,也不需要重新生成keyfactory。因为具体我也没应用过,可能是实际项目中一般会这样,因为实际接受方和发送方并不知道对方的密钥的encoded format(编码格式),所以需要转换成自己使用encoded format。而KeyFactory就是转换格式后重新生成私钥,公钥。

总结:
1、对称加密算法中使用的是密钥(SecretKey),非对称加密算法中使用的是密钥对(公钥、私钥)。
2、DH算法比较复杂,需要根据公钥生成自己的秘钥对,然后使用公钥和自己的私钥生成自己的本地秘钥在进行加密
3、RSA相对来讲简单的多,支持公钥加密、私钥解密,私钥加密、公钥解密。
4、ElGamal算法和RSA类似,但是只支持公钥加密,私钥解密,不支持私钥加密,公钥解密。

源码地址:https://github.com/allanzhuo/study

java加密算法入门(三)-非对称加密详解的更多相关文章

  1. JAVA RSA非对称加密详解[转载]

    一.概述1.RSA是基于大数因子分解难题.目前各种主流计算机语言都支持RSA算法的实现2.java6支持RSA算法3.RSA算法可以用于数据加密和数字签名4.RSA算法相对于DES/AES等对称加密算 ...

  2. java加密算法入门(二)-对称加密详解

    1.简单介绍 什么是对称加密算法? 对称加密算法即,加密和解密使用相同密钥的算法. 优缺点: 优点:算法公开.计算量小.加密速度快.加密效率高. 缺点: (1)交易双方都使用同样钥匙,安全性得不到保证 ...

  3. 爬虫入门之urllib库详解(二)

    爬虫入门之urllib库详解(二) 1 urllib模块 urllib模块是一个运用于URL的包 urllib.request用于访问和读取URLS urllib.error包括了所有urllib.r ...

  4. java的集合框架最全详解

    java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作 ...

  5. 【转】Java魔法堂:String.format详解

    Java魔法堂:String.format详解     目录     一.前言    二.重载方法     三.占位符     四.对字符.字符串进行格式化     五.对整数进行格式化     六. ...

  6. java线程池的使用与详解

    java线程池的使用与详解 [转载]本文转载自两篇博文:  1.Java并发编程:线程池的使用:http://www.cnblogs.com/dolphin0520/p/3932921.html   ...

  7. MD5加密详解

    MD5加密详解 引言: 我在百度百科上查找到了关于MD5的介绍,我从中摘要一些重要信息: Message Digest Algorithm MD5(中文名为信息摘要算法第五版)为计算机安全领域广泛使用 ...

  8. Java之Static静态修饰符详解

    Java之Static静态修饰符详解 Java之Static静态修饰符详解 一.特点 1.随着类的加载而加载,随着类的消失而消失,生命周期最长 2.优先于对象存在 3.被所有类的对象共享 4.可以直接 ...

  9. Java线程创建形式 Thread构造详解 多线程中篇(五)

    Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制. 创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象. 构造方法列表 ...

随机推荐

  1. 在C#中使用类golang信道编程(一)

    BusterWood.Channels是一个在C#上实现的信道的开源库.通过使用这个类库,我们可以在C#语言中实现类似golang和goroutine的信道编程方式.在这里我们介绍3个简单的信道的例子 ...

  2. 浅谈JavaScript时间与正则表达式

    时间函数:var box = new Date() 函数       Demo:         alert(Date.parse('4/12/2007'));    //返回的是一个毫秒数11763 ...

  3. 蓝桥杯-趣味算式-java

    /* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...

  4. futex-based pthread_cond

    pthread_cond的实现使用了几个futex来协同进行同步,以及如何来实现的. 假定你已经明白 futex,futex-requeue,以及 pthread lowlevellock. < ...

  5. Docker - 在Ubuntu16.04中安装Docker CE

    Get Docker for Ubuntu Check system version root@Ubuntu16:~# uname -a Linux Ubuntu16 4.8.0-36-generic ...

  6. hdu 4552 怪盗基德的挑战书

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4552 思路: 其实可以用KMP+DP解决 我这里给出后缀数组的解题方法 思路: 初始化ans=n(n为 ...

  7. 北京赛车PK10 幸运飞艇 重庆时时彩 PC蛋蛋 快乐8 福彩3D 十分彩

    QQ:1395239152 2017-3.14最新修复完整运营版时时彩源码PC+手机版本功能齐全 重庆时时彩是一种经中国国家财政部批准,重庆市福利彩票发行中心承销的福彩快开彩票,2元1注,分为&quo ...

  8. git学习笔记之二 -- git分支

    前面对git基础作了简单的总结,这次对git的杀手锏--分支做一总结. Git分支简介 几乎每个版本控制系统都以某种形式支持分支,可以使你的工作从开发主线上分离开来,以免影响开发主线.很多版本控制系统 ...

  9. [转]亿级Web系统搭建:单机到分布式集群

    当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要在Web系统架构层 ...

  10. 利用有限自动机(finite automata)进行模式匹配

    一.有限自动机定义及基本术语: 一个有限自动机 M 是一个5元组(Q, ,A, Σ, δ),其中: Q 是所有状态的有限集合;  ∈ Q (属于)是初始状态; A ⊆ Q (子集)是接受状态的集合; ...