转:常用的几种加密算法以及java实现

转自:  https://blog.csdn.net/wqwqwqwq403/article/details/103948952

 

工作中经常会接触到一些加密算法,比如说base64、MD5、DES、AES等等,那么这些算法到底有什么区别以及具体的应用场景是什么呢,下面就做个简要的梳理。

一、什么是加/解密,目的是什么?

所谓加密,就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为 “密文”。目的就是保护数据不被非法窃取、阅读。
所谓解密,也就是加密的逆过程,即将该密文信息转化为其原来数据的过程。
举个例子:小王想给他的妻子写一封信,如果在邮寄的过程中,被他人截获那么就显而易见的将信息泄露掉。相反如果小王根据一个密码本将信的内容加密,比如每一个汉字对应一个编码,那么即使被别人截获,因为没有密码本那么信息也不会泄露,小王的妻子拿到加密后的信件后,用密码本再一一翻译成可读的文本,这个过程就是解密。

二、什么是加/解密算法

加密/解密过程中,使用到的算法就是加密/解密算法。

三、加/解密算法的分类

根据加/解密过程是否可逆,算法可以分为可逆加密算法和不可逆加密算法
可逆算法包括:DES、3DES、AES、RSA、DSA
不可逆加密算法包括:SHA-1、MD5
对于可逆加密,如果没有秘钥,任何人拿到了密文后通过对应的可逆算法都可以解密,这是不安全的。所以引入了秘钥,加密的时候加入了秘钥,接收方解密时需提供秘钥,这样不知道秘钥就无法解密。
根据加解密使用的秘钥是否相同,算法可以分为对称加密算法和非对称加密算法
对称加解密使用的秘钥是一致的,非对称加解密使用的秘钥是不一致的。

四、不可逆算法

4.1 MD5加密算法

MD5 用的是哈希函数。严格来说,MD5不是一种加密算法而是摘要算法。无论是多长的输入,MD5 都会输出长度为 128bits 的一个串 (通常用 16 进制 表示为 32 个字符)。完整的md5一般是32位,国内常见的一种是动网的16位(也就是只取32位md5的中间16位),另外有一种是变化过的md5,特征是全是数字,长度可能是20位或者19。

它的典型应用是对一段信息产生信息摘要,以 防止被篡改。
防止被篡改的意思是,发送方用此算法对一段信息产生一个摘要串,接收方也用此算法产生一个摘要串,然后比较这两个摘要串的内容是否一致,如果不一致我们就认为此信息在传输的过程中可能发生了篡改。
那么有没有可能我修改了信息内容,修改后的内容产生的md5与修改之前是一致的呢?md5防止篡改的关键在于,它的碰撞算法以前一直没有找到,所谓碰撞算法,就是修改原来的文件,同时保持修改后的文件和原文件md5一致。
不过后来,我国山东大学的杨教授搞定了碰撞算法。所以md5作为防篡改,已经不可靠了。类似的,sha1的碰撞算法,最近也被攻克。

 public static String getMd5(String source) throws NoSuchAlgorithmException {//1.获取MessageDigest对象MessageDigest digest = MessageDigest.getInstance("md5");//2.执行加密操作byte[] bytes = source.getBytes();//在MD5算法这,得到的目标字节数组的特点:长度固定为16byte[] targetBytes = digest.digest(bytes);//3.声明字符数组char [] characters = new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};//4.遍历targetBytesStringBuilder builder = new StringBuilder();for (byte b : targetBytes) {//5.取出b的高四位的值//先把高四位通过右移操作拽到低四位int high = (b >> 4) & 15;//6.取出b的低四位的值int low = b & 15;//7.以high为下标从characters中取出对应的十六进制字符char highChar = characters[high];//8.以low为下标从characters中取出对应的十六进制字符char lowChar = characters[low];builder.append(highChar).append(lowChar);}return builder.toString();}

4.2 SHA-1加密算法

SHA1 是和 MD5 一样流行的 消息摘要算法,然而 SHA1 比 MD5 的 安全性更强。对于长度小于 2 ^ 64 位的消息,SHA1 会产生一个 160 位(40个字符)的 消息摘要。基于 MD5、SHA1 的信息摘要特性以及 不可逆 (一般而言),可以被应用在检查 文件完整性 以及 数字签名 等场景。

public static String shaEncode(String inStr) throws Exception {MessageDigest sha = null;try {sha = MessageDigest.getInstance("SHA");} catch (Exception e) {System.out.println(e.toString());e.printStackTrace();return "";}byte[] byteArray = inStr.getBytes("UTF-8");byte[] md5Bytes = sha.digest(byteArray);StringBuffer hexValue = new StringBuffer();for (int i = 0; i < md5Bytes.length; i++) {int val = ((int) md5Bytes[i]) & 0xff;if (val < 16) {hexValue.append("0");}hexValue.append(Integer.toHexString(val));}return hexValue.toString();}

五、对称加密算法

5.1 DES算法

DES(Data Encryption Standard)是一种分组密码算法,明文按 64 位进行分组,密钥长 64 位,密钥事实上是 56 位参与 DES 运算(第8、16、24、32、40、48、56、64 位是校验位)分组后的明文组和 56 位的密钥按位替代或交换的方法形成密文组,之后按照顺序将密文组连在一起,各段数据之间互不影响。标准的DES密钥长度为64bit,即8个字符,超过8个字符则舍弃后面。比如:用abcdefgh与abcdefghi加密是一样的结果。又因为有校验位的存在,所以用12345678与13345678进行加密是一样的。
如果密钥长度不足,会以指定的填充方式( 比如PKCS7Padding )方式补足位
关于数据补位参考:https://www.cnblogs.com/Lawson/archive/2012/05/20/2510781.html
因此,破译 DES 加密算法实际上就是 搜索密钥的编码。对于56 位长度的密钥 来说,如果用穷举法来进行搜索的话,其运算次数为 2 ^ 56 次=非常大的一个数。
des原理描述
https://blog.csdn.net/qq_32445015/article/details/80184954

package com.inspur.incloudmanager.controller.util;import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.util.Base64;public class DESUtil {/*** 偏移变量,固定占8位字节*/private final static String IV_PARAMETER = "12345678";/*** 密钥算法*/private static final String ALGORITHM = "DES";/*** 加密/解密算法-工作模式-填充模式*/
//    private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding";private static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";/*** 默认编码*/private static final String CHARSET = "utf-8";/*** 生成key** @param password* @return* @throws Exception*/private static Key generateKey(String password) throws Exception {DESKeySpec dks = new DESKeySpec(password.getBytes(CHARSET));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);return keyFactory.generateSecret(dks);}/*** DES加密字符串** @param password 加密密码,长度不能够小于8位* @param data 待加密字符串* @return 加密后内容*/public static String encrypt(String password, String data) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能小于8位");}if (data == null)return null;try {Key secretKey = generateKey(password);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));//非ECB模式使用下面的偏移量
//            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);//ECB模式cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] bytes = cipher.doFinal(data.getBytes(CHARSET));//JDK1.8及以上可直接使用Base64,JDK1.7及以下可以使用BASE64Encoder//Android平台可以使用android.util.Base64return new String(Base64.getEncoder().encode(bytes));} catch (Exception e) {e.printStackTrace();return data;}}/*** DES解密字符串** @param password 解密密码,长度不能够小于8位* @param data 待解密字符串* @return 解密后内容*/public static String decrypt(String password, String data) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能小于8位");}if (data == null)return null;try {Key secretKey = generateKey(password);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));//非ECB模式使用下面的偏移量
//            cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);cipher.init(Cipher.DECRYPT_MODE, secretKey);return new String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes(CHARSET))), CHARSET);} catch (Exception e) {e.printStackTrace();return data;}}
}
  •  

5.2 3DES算法

3DES(又叫Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。密钥长度是128位,192位(bit),如果密码位数少于等于64位,加密结果与DES相同。原版DES容易被破解,新的3DES出现,增加了加密安全性,避免被暴力破解。它同样是对称性加密,同样涉及到加密编码方式,及填充方式。包括3DES-ECB,3DES-CBC,3DES-CTR,3DES-OFB,3DES-CFB

public static String threedesencrypt(String key,String text) {try {byte[] src = text.getBytes();DESedeKeySpec spec = new DESedeKeySpec(convert(key.getBytes()));SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");SecretKey secretKey = factory.generateSecret(spec);Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] res = cipher.doFinal(src);//encodeBase64会对字符串3位一组自动补全,因而最后可能会出现 == 或者 =return new String(Base64.getEncoder().encode(res), "utf-8");} catch (Exception e) {System.out.println("error");}return null;}/*** 不足24位进行补位* @param sources* @return*/private static byte[] convert(byte[] sources){byte[] ret = new byte[24];if(sources.length < 24){for(int i = 0; i < 24;i++){if(i < sources.length){ret[i] = sources[i];}else{ret[i] = 0;}}}else{ret = sources;}return ret;}
  •  

5.3 AES算法

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
那么为什么原来的DES会被取代呢,原因就在于其使用56位密钥,比较容易被破解。而AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据,相对来说安全很多。完善的加密算法在理论上是无法破解的,除非使用穷尽法。使用穷尽法破解密钥长度在128位以上的加密数据是不现实的,仅存在理论上的可能性。统计显示,即使使用目前世界上运算速度最快的计算机,穷尽128位密钥也要花上几十亿年的时间,更不用说去破解采用256位密钥长度的AES算法了。

package com.inspur.incloudmanager.controller.util;import org.springframework.util.Base64Utils;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;public class AESUtil{private static final String KEY_ALGORITHM = "AES";private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法/*** AES 加密操作** @param content 待加密内容* @param key 加密密钥* @return 返回Base64转码后的加密数据*/public static String encrypt(String content, String key) {try {Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器byte[] byteContent = content.getBytes("utf-8");cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));// 初始化为加密模式的密码器byte[] result = cipher.doFinal(byteContent);// 加密return Base64Utils.encodeToString(result);//通过Base64转码返回} catch (Exception ex) {Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);}return null;}/*** AES 解密操作** @param content* @param key* @return*/public static String decrypt(String content, String key) {try {//实例化Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);//使用密钥初始化,设置为解密模式cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));//执行操作byte[] result = cipher.doFinal(Base64Utils.decodeFromString(content));return new String(result, "utf-8");} catch (Exception ex) {Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);}return null;}/*** 生成加密秘钥** @return*/private static SecretKeySpec getSecretKey(final String key) {//返回生成指定算法密钥生成器的 KeyGenerator 对象KeyGenerator kg = null;try {kg = KeyGenerator.getInstance(KEY_ALGORITHM);//AES 要求密钥长度为 128kg.init(128, new SecureRandom(key.getBytes()));//生成一个密钥SecretKey secretKey = kg.generateKey();return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥} catch (NoSuchAlgorithmException ex) {Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);}return null;}public static void main(String[] args) {String content = "Inspur1!";String key = "wang";System.out.println("content:" + content);String s1 = AESUtil.encrypt(content, key);System.out.println("s1:" + s1);System.out.println("s2:"+AESUtil.decrypt(s1, key));}}

指定秘钥

public class AESUtil{private static final String KEY_ALGORITHM = "AES";private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法/*** AES 加密操作** @param content 待加密内容* @param key 加密密钥* @return 返回Base64转码后的加密数据*/public static String encrypt(String content, String key) {try {Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器byte[] byteContent = content.getBytes("utf-8");SecretKeySpec aeskey = new SecretKeySpec(convert(key.getBytes("utf-8")), "AES");cipher.init(Cipher.ENCRYPT_MODE, aeskey);// 初始化为加密模式的密码器byte[] result = cipher.doFinal(byteContent);// 加密return Base64Utils.encodeToString(result);//通过Base64转码返回} catch (Exception ex) {Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);}return null;}/*** AES 解密操作** @param content* @param key* @return*/public static String decrypt(String content, String key) {try {//实例化Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);SecretKeySpec aeskey = new SecretKeySpec(convert(key.getBytes("UTF-8")), "AES");//使用密钥初始化,设置为解密模式cipher.init(Cipher.DECRYPT_MODE, aeskey);//执行操作byte[] result = cipher.doFinal(Base64Utils.decodeFromString(content));return new String(result, "utf-8");} catch (Exception ex) {Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);}return null;}/*** 截取算法,超过128位(32字节),手动截取掉* @param sources* @return*/private static byte[] convert(byte[] sources){byte[] ret = new byte[32];if(sources.length > 32){for(int i = 0; i < 32;i++){ret[i] = sources[i];}}else{ret = sources;}return ret;}public static void main(String[] args) {String content = "Inspur1!";String key = "inclouqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";System.out.println("content:" + content);String s1 = AESUtil.encrypt(content, key);System.out.println("s1:" + s1);System.out.println("s2:"+AESUtil.decrypt(s1, key));}
}
  •  

六、非对称加密算法

6.1 RSA算法

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;/*** RSA非对称加密算法工具类** @author lixk*/public class RSA {//非对称密钥算法private static final String KEY_ALGORITHM = "RSA";//密钥长度,在512到65536位之间,建议不要太长,否则速度很慢,生成的加密数据很长private static final int KEY_SIZE = 512;//字符编码private static final String CHARSET = "UTF-8";/*** 生成密钥对** @return KeyPair 密钥对*/public static KeyPair getKeyPair() throws Exception {return getKeyPair(null);}/*** 生成密钥对* @param password 生成密钥对的密码* @return* @throws Exception*/public static KeyPair getKeyPair(String password) throws Exception {//实例化密钥生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);//初始化密钥生成器if(password == null){keyPairGenerator.initialize(KEY_SIZE);}else {SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(password.getBytes(CHARSET));keyPairGenerator.initialize(KEY_SIZE, secureRandom);}//生成密钥对return keyPairGenerator.generateKeyPair();}/*** 取得私钥** @param keyPair 密钥对* @return byte[] 私钥*/public static byte[] getPrivateKeyBytes(KeyPair keyPair) {return keyPair.getPrivate().getEncoded();}/*** 取得Base64编码的私钥** @param keyPair 密钥对* @return String Base64编码的私钥*/public static String getPrivateKey(KeyPair keyPair) {return Base64.getEncoder().encodeToString(getPrivateKeyBytes(keyPair));}/*** 取得公钥** @param keyPair 密钥对* @return byte[] 公钥*/public static byte[] getPublicKeyBytes(KeyPair keyPair) {return keyPair.getPublic().getEncoded();}/*** 取得Base64编码的公钥** @param keyPair 密钥对* @return String Base64编码的公钥*/public static String getPublicKey(KeyPair keyPair) {return Base64.getEncoder().encodeToString(getPublicKeyBytes(keyPair));}/*** 私钥加密** @param data       待加密数据* @param privateKey 私钥字节数组* @return byte[] 加密数据*/public static byte[] encryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception {//实例化密钥工厂KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成私钥PrivateKey key = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey));//数据加密Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, key);return cipher.doFinal(data);}/*** 私钥加密** @param data       待加密数据* @param privateKey Base64编码的私钥* @return String Base64编码的加密数据*/public static String encryptByPrivateKey(String data, String privateKey) throws Exception {byte[] key = Base64.getDecoder().decode(privateKey);return Base64.getEncoder().encodeToString(encryptByPrivateKey(data.getBytes(CHARSET), key));}/*** 公钥加密** @param data      待加密数据* @param publicKey 公钥字节数组* @return byte[] 加密数据*/public static byte[] encryptByPublicKey(byte[] data, byte[] publicKey) throws Exception {//实例化密钥工厂KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成公钥PublicKey key = keyFactory.generatePublic(new X509EncodedKeySpec(publicKey));//数据加密Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, key);return cipher.doFinal(data);}/*** 公钥加密** @param data      待加密数据* @param publicKey Base64编码的公钥* @return String Base64编码的加密数据*/public static String encryptByPublicKey(String data, String publicKey) throws Exception {byte[] key = Base64.getDecoder().decode(publicKey);return Base64.getEncoder().encodeToString(encryptByPublicKey(data.getBytes(CHARSET), key));}/*** 私钥解密** @param data       待解密数据* @param privateKey 私钥字节数组* @return byte[] 解密数据*/public static byte[] decryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception {//实例化密钥工厂KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成私钥PrivateKey key = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey));//数据解密Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, key);return cipher.doFinal(data);}/*** 私钥解密** @param data       Base64编码的待解密数据* @param privateKey Base64编码的私钥* @return String 解密数据*/public static String decryptByPrivateKey(String data, String privateKey) throws Exception {byte[] key = Base64.getDecoder().decode(privateKey);return new String(decryptByPrivateKey(Base64.getDecoder().decode(data), key), CHARSET);}/*** 公钥解密** @param data      待解密数据* @param publicKey 公钥字节数组* @return byte[] 解密数据*/public static byte[] decryptByPublicKey(byte[] data, byte[] publicKey) throws Exception {//实例化密钥工厂KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//产生公钥PublicKey key = keyFactory.generatePublic(new X509EncodedKeySpec(publicKey));//数据解密Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, key);return cipher.doFinal(data);}/*** 公钥解密** @param data      Base64编码的待解密数据* @param publicKey Base64编码的公钥* @return String 解密数据*/public static String decryptByPublicKey(String data, String publicKey) throws Exception {byte[] key = Base64.getDecoder().decode(publicKey);return new String(decryptByPublicKey(Base64.getDecoder().decode(data), key), CHARSET);}/*** 测试加解密方法** @param args* @throws Exception*/public static void main(String[] args) throws Exception {//生成密钥对,一般生成之后可以放到配置文件中KeyPair keyPair = RSA.getKeyPair();//公钥String publicKey = RSA.getPublicKey(keyPair);//私钥String privateKey = RSA.getPrivateKey(keyPair);System.out.println("公钥:\n" + publicKey);System.out.println("私钥:\n" + privateKey);String data = "RSA 加解密测试!";{System.out.println("\n===========私钥加密,公钥解密==============");String s1 = RSA.encryptByPrivateKey(data, privateKey);System.out.println("加密后的数据:" + s1);String s2 = RSA.decryptByPublicKey(s1, publicKey);System.out.println("解密后的数据:" + s2 + "\n\n");}{System.out.println("\n===========公钥加密,私钥解密==============");String s1 = RSA.encryptByPublicKey(data, publicKey);System.out.println("加密后的数据:" + s1);String s2 = RSA.decryptByPrivateKey(s1, privateKey);System.out.println("解密后的数据:" + s2 + "\n\n");}}
}

声明:本文章主要将几种常用的加密算法及其java实现统一整理,便于以后查看。大多数是转载参考网上的内容。如有侵权请告知。
参考文章列表如下:

https://blog.csdn.net/u013314786/article/details/80324461

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330294.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA 实现 JWT

引入JWT依赖,由于是基于Java&#xff0c;所以需要的是java-jwt <dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.4.0</version> </dependency>自定义注解用于判断是否需要验证 用来跳…

SaaS,PaaS,IaaS都是什么鬼

转载自 SaaS,PaaS,IaaS都是什么鬼IaaS Infrastructure as a Service&#xff0c;基础设施即服务。 假如你现在要做一个网站&#xff0c;你肯定要有一台服务器或者虚拟机&#xff0c;要么自己搭建&#xff0c;要么买服务器运营商的。说白了&#xff0c;IaaS就是解决企业硬件问题…

转:什么是 Base64编码

转&#xff1a; https://developer.aliyun.com/article/763589 一、定义 Base64编码 是一种基于 64 个可打印字符来表示二进制数据的方法。目前 Base64 已经成为网络上常见的传输 8 位二进制字节代码的编码方式之一。为什么会有 Base64 编码呢&#xff1f;&#xff08;Base…

什么是Spring Boot?

转载自 什么是Spring Boot? 什么是Spring Boot? Spring Boot是Spring开源组织下的子项目&#xff0c;是Spring组件一站式解决方案&#xff0c;主要是简化了使用Spring的难度&#xff0c;简省了繁重的配置&#xff0c;提供了各种启动器&#xff0c;开发者能快速上手。 官方网站…

JAVA并发知识

JAVA并发知识一、什么是线程和进程&#xff1f;二、线程与进程的关系&#xff0c;区别及优缺点&#xff1f;三、并发和并行有什么区别&#xff1f;四、为什么要使用多线程&#xff1f;五、使用多线程可能会带来什么问题&#xff1f;六、说说线程的生命周期和状态。七、java 中如…

servlet session持久化

1、 session持久化是什么&#xff1f; web服务器把 session中存储的属性存储到本地磁盘或数据库中&#xff1b; 2、为什么需要持久化&#xff1f; 因为 session是服务器维护会话状态的对象&#xff0c;即便客户端关闭连接或客户端长时间没有访问&#xff0c;服务器还依然存储…

高并发解决方案

扩容 垂直扩容&#xff1a;提高系统部件能力水平扩容&#xff1a;增加更多系统成员&#xff08;增加服务器数量&#xff09; 数据库扩容系统属于 读操作 频繁型&#xff0c;可采用垂直扩容 采用 memcache&#xff0c; redis&#xff0c; CDN等缓存系统属于 写操作 频繁型&#…

servlet session 跟踪用户上次访问时间

1、是什么&#xff1f; 上次访问时间&#xff1b;即用户最近一次登录时间&#xff1b; 2、为什么&#xff1f; 为了提示用户登录或访问记录&#xff0c;提高安全性&#xff0c;如qq登录提示&#xff1b; 3、怎么做&#xff1f; 通过cookie 实现&#xff1b; 用户第1次登录&…

Spring MVC表单防重复提交

转载自 Spring MVC表单防重复提交 利用Spring MVC的过滤器及token传递验证来实现表单防重复提交。 创建注解 Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) Documented public interface Token {boolean create() default false;boolean remove() default f…

SpringMvc @RequestParam、 @RequestBody、@RequestPart 的区别

注解RequestParam接收的参数是来自requestHeader中&#xff0c;即请求头。 RequestParam可以接受简单类型的属性&#xff0c;也可以接受对象类型。 RequestParam有三个配置参数&#xff1a; required 表示是否必须&#xff0c;默认为 true&#xff0c;必须。defaultValue 可…

利用session防止表单重复提交

1、是什么&#xff1f;一个表单不能多次提交&#xff1b; 2、为什么&#xff1f; 在网络不好或者并发请求时会导致多次重复提交数据的问题。防止重复提交&#xff0c;可以维护数据一致性&#xff1b; 3、怎么做&#xff1f; 把 session的编号和当前时间戳经过 MD5 加密得到to…

Druid-目前最好的连接池

转载自 Druid-目前最好的连接池 Druid是什么 Druid是阿里开源的连接池&#xff0c;是Java语言中最好的数据库连接池.Druid能够提供强大的监控和扩展功能&#xff0c;是为监控而生的数据库连接池&#xff01; GitHub&#xff1a;https://github.com/alibaba/druid/ 添加依赖 &l…

Nginx 部署 Vue 项目刷新页面出现404

问题 使用Vue.框架&#xff0c;利用vue-route编写了一个单页路由项目&#xff0c;运维协助在服务器端配置nginx。部署完成后&#xff0c;访问首页没问题&#xff0c;从首页里打开二级页面没问题&#xff0c;但是所有的二级页面打开后&#xff0c;再次刷新&#xff0c;就会出现…

repost: intro2token

repost 4 https://blog.csdn.net/Jason_Fangh/article/details/55113627 对于初学者来说&#xff0c;对Token和Session的使用难免会限于困境&#xff0c;开发过程中知道有这个东西&#xff0c;但却不知道为什么要用他&#xff1f;更不知道其原理&#xff0c;今天我就带大家一…

vue - resource 使用过程的坑

一. get 传参的坑&#xff1a;加params对象传参&#xff08;不能直接get(url, params)!!!&#xff09; this.$http.get(url, {params: { offset: this.offset, label: this.categray }})二. 使用post请求&#xff1a; 知识点 post参数的形式 form data(表单&#xff0c;通过url…

repo-关于URL编码

repost 4 http://www.ruanyifeng.com/blog/2010/02/url_encoding.html 一、问题的由来 URL就是网址&#xff0c;只要上网&#xff0c;就一定会用到。 一般来说&#xff0c;URL只能使用英文字母、阿拉伯数字和某些标点符号&#xff0c;不能使用其他文字和符号。比如&#xff0c…

Spring零配置之@Configuration注解详解

转载自 Spring零配置之Configuration注解详解 Configuration介绍 Spring3.0之前要使用Spring必须要有一个xml配置文件&#xff0c;这也是Spring的核心文件&#xff0c;而Spring3.0之后可以不要配置文件了&#xff0c;通过注解Configuration完全搞定。 Configuration即用来代替S…

session实现购物车

1、是什么&#xff1f; session 可以存储会话级变量&#xff0c;基于其实现购物车&#xff1b; 2、为什么&#xff1f; session是会话级变量&#xff0c;可以吧多次请求的数据串联起来&#xff0c;放到会话里&#xff1b; 3、怎么做&#xff1f; 【荔枝】转自 张孝祥 登录…

commons-logging,log4j,logback,slf4j之间的关系详解

转载自 commons-logging,log4j,logback,slf4j之间的关系详解commons-logging是apache最早提供的日志的门面接口。它的主要作用是提供一个日志门面&#xff0c;使用者可以使用不同的日志实现。用户可以自由选择第三方的日志组件作为具体实现&#xff0c;像log4j&#xff0c;或者…

Vue代理配置

在 package.json 的同级目录&#xff08;项目根目录&#xff09;下创建 vue.config.js在 vue.config.js 写入下列内容 module.exports {devServer: {proxy: http://localhost:8080}}这会告诉开发服务器将任何未知请求 (没有匹配到静态文件的请求) 代理到 http://localhost:40…