密码学【java】初探究加密方式之对称加密

news2025/2/23 5:03:37

文章目录

  • 一 常见加密方式
  • 二 对称加密
    • 2.1 Cipher类简介
    • 2.2 Base算法
    • 2.3 补充:Byte&bit
    • 2.4 DES加密演示
    • 2.5 DES解密
    • 2.6 补充:对于IDEA控制台乱码的解决方法
    • 2.7 AES加密解密
    • 2.8 补充: toString()与new String ()用法区别
    • 2.9 加密模式
      • 2.9.1 ECB
      • 2.9.2 CBC
    • 2.10 填充模式
      • 2.10.1 NoPadding
      • 2.10.2 PKCS5Padding
      • 2.10.3 Tips
    • 2.11 加密模式和填充模式演示

一 常见加密方式

在这里插入图片描述

二 对称加密

  • 对称加密:采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密
  • 示例:现在有一个原文3要发送给B
    • 设置密钥为108, 3 * 108 = 324, 将324作为密文发送给B
    • B拿到密文324后, 使用324/108 = 3 得到原文
  • 常见加密算法
    • DES : Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。
    • AES : Advanced Encryption Standard, 高级加密标准 .在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

  • 特点
    • 加密速度快, 可以加密大文件
    • 密文可逆, 一旦密钥文件泄漏, 就会导致数据暴露
    • 加密后编码表找不到对应字符, 出现乱码
    • 一般结合Base64使用

2.1 Cipher类简介

  • 该类提供加密和解密的加密密码的功能。 它构成了Java加密扩展(JCE)框架的核心。
  • 为了创建一个Cipher对象,应用程序调用Cipher的getInstance方法,并将所请求的转换的名称传递给它。 可选地指定提供者的名称。
  • 转换是描述要在给定输入上执行的操作(或操作集)的字符串,以产生一些输出。 转换包括**:加密算法的名称(例如, DES ),并且可以跟随有反馈模式和填充方案。**
  • 转换形式如下:
- “ 算法/模式/填充 ”或“ 算法 ”  
Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding"); 
- 在该一种情况下,使用模式和填充方案的提供者特定的默认值
Cipher c = Cipher.getInstance("DES"); 

2.2 Base算法

  • Base64:在编码过程中使用了64种字符:大写A到Z、小写a到z、数字0到9、“+”和“/”
  • Base64是网络上最常见的用于传输8Bit字节码的可读性编码算法之一
  • 可读性编码算法不是为了保护数据的安全性,而是为了可读性。可读性编码不改变信息内容,只改变信息内容的表现形式
  • Base58是Bitcoin(比特币)中使用的一种编码方式,主要用于产生Bitcoin的钱包地址。相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"i",以及"+“和”/"符号。

  • Base64算法原理
  • base64 是 3个字节为一组,一个字节 8位,一共 就是24位 ,然后,把3个字节转成4组,每组6位, 3 ∗ 8 = 4 ∗ 6 = 24 3 * 8 = 4 * 6 = 24 38=46=24 ,每组6位,缺少的2位,会在高位进行补0 ,这样做的好处在于 ,base取的是后面6位,去掉高2位 ,那么base64的取值就可以控制在0-63位了,所以就叫base64,111 111 = 32 + 16 + 8 + 4 + 2 + 1 =64.
  • base64是三个字节一组 ,如果当我们的位数不够的时候,会使用等号来补齐
    在这里插入图片描述

2.3 补充:Byte&bit

  • Byte : 字节. 数据存储的基本单位,比如移动硬盘1T , 单位是byte
  • bit : 比特/位.。要么是0要么是1. 数据传输的单位 , 比如家里的宽带100Mb,下载速度并没有达到100MB,一般都是12-13MB,那么是因为需要使用 100 / 8 MB
  • 关系: 1Byte = 8bit

  • 演示
    public class ByteBit {
        public static void main(String[] args) {
            String a = "a";
            byte[] bytes = a.getBytes();
            for (byte aByte : bytes) {
                int c = aByte;
                System.out.println(c);
                // byte 字节,对应的bit是多少
                String s = Integer.toBinaryString(c);
                System.out.println(s);
            }
        }
    }
    
      ![在这里插入图片描述](https://img-blog.csdnimg.cn/2e86e1293f5b4216bc0fe5c4cf3736fa.png)
    

  • 一个英文字母对应的字节
public static void main(String[] args) throws Exception{
        String a = "A";
        byte[] bytes = a.getBytes();
        for (byte aByte : bytes) {
            System.out.println(aByte);
            String s = Integer.toBinaryString(aByte);
            System.out.println(s);
        }
    }

  • 在utf-8编码格式下,一个中文对应三个字节
  • 在GBK编码格式下,一个中文对应两个字节
public static void main(String[] args) throws Exception{
        String a = "天";
        byte[] bytes = a.getBytes();
        for (byte aByte : bytes) {
            System.out.println(aByte);
            String s = Integer.toBinaryString(aByte);
            System.out.println(s);
        }
    }

在这里插入图片描述

public static void main(String[] args) throws Exception{
        String a = "天";
        byte[] bytes = a.getBytes("GBK");
        for (byte aByte : bytes) {
            System.out.println(aByte);
            String s = Integer.toBinaryString(aByte);
            System.out.println(s);
        }
    }

在这里插入图片描述

2.4 DES加密演示

public static void main(String[] args) throws Exception{
        // 原文
        String input = "天下";
        // des加密必须是8位
        String key = "12345678";
        // 算法
        String algorithm = "DES";

        String transformation = "DES";
        
        // Cipher:密码,获取加密对象
        // transformation:表示使用什么类型加密
        Cipher cipher = Cipher.getInstance(transformation);
        /*	第一步:指定秘钥规则
         		第一个参数表示:密钥,key的字节数组
         		第二个参数表示:算法
        */
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        /* 
         第二步:对加密进行初始化
         	第一个参数:表示模式,有加密模式和解密模式
         	第二个参数:表示秘钥规则
        */
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 第三步:进行加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        
        // 打印密文,因为ascii码有负数,解析不出来,所以乱码
        System.out.println(new String(bytes));
        //
    }
  • 注意:DES加密算法规定,密匙必须是八个字节,否做会出现以下错误
java.security.InvalidKeyException: Wrong key size

	at java.base/com.sun.crypto.provider.DESCrypt.init(DESCrypt.java:536)
	at java.base/com.sun.crypto.provider.ElectronicCodeBook.init(ElectronicCodeBook.java:97)
	at java.base/com.sun.crypto.provider.CipherCore.init(CipherCore.java:481)
	at java.base/com.sun.crypto.provider.CipherCore.init(CipherCore.java:399)
	at java.base/com.sun.crypto.provider.DESCipher.engineInit(DESCipher.java:187)
	at java.base/javax.crypto.Cipher.implInit(Cipher.java:869)
	at java.base/javax.crypto.Cipher.chooseProvider(Cipher.java:931)
	at java.base/javax.crypto.Cipher.init(Cipher.java:1301)
	at java.base/javax.crypto.Cipher.init(Cipher.java:1238)
	at DESTest.test1(DESTest.java:31)
  • 注意:出现乱码是因为对应的字节出现负数,但负数,没有出现在 ascii 码表里面,所以出现乱码,需要配合base64进行转码
    在这里插入图片描述
    • 注意:导入的包为org.apache.commons.codec.binary.Base64;
    import org.apache.commons.codec.binary.Base64;
    //对数据进行Base64编码
     String s = Base64.encodeBase64String(bytes);
     System.out.println(s);
    

在这里插入图片描述

2.5 DES解密


import org.junit.Test;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class DESTest {
    @Test
    public  void test() throws Exception {
        String input ="天下";
        // DES加密算法,key的大小必须是8个字节
        String key = "12345678";

        String transformation = "DES";
        // 指定获取密钥的算法
        String algorithm = "DES";
        String encryptDES = encryptDES(input, key, transformation, algorithm);
        System.out.println("加密:" + encryptDES);

        String s = decryptDES(encryptDES, key, transformation, algorithm);
        System.out.println("解密:" + s);

    }

    /**
     * 使用DES加密数据
     *
     * @param input          : 原文
     * @param key            : 密钥(DES,密钥的长度必须是8个字节)
     * @param transformation : 获取Cipher对象的算法
     * @param algorithm      : 获取密钥的算法
     * @return : 密文
     * @throws Exception
     */
    private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 获取加密对象
        Cipher cipher = Cipher.getInstance(transformation);
        // 创建加密规则
        // 第一个参数key的字节
        // 第二个参数表示加密算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // ENCRYPT_MODE:加密模式
        // 初始化加密模式和算法
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 加密
        byte[] bytes = cipher.doFinal(input.getBytes());

        // 输出加密后的数据
        String encode = Base64.encodeBase64String(bytes);

        return encode;
    }

    /**
     * 使用DES解密
     *
     * @param input          : 密文
     * @param key            : 密钥
     * @param transformation : 获取Cipher对象的算法
     * @param algorithm      : 获取密钥的算法
     * @throws Exception
     * @return: 原文
     */
    private static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 1,获取Cipher对象
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定密钥规则
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // DECRYPT_MODE: 解密模式
        cipher.init(Cipher.DECRYPT_MODE, sks);
        // 3. 解密,上面使用的base64编码,下面直接用密文
        byte[] bytes = cipher.doFinal(Base64.decodeBase64(input));
        //  因为是明文,所以直接返回
        return new String(bytes);
    }
}

在这里插入图片描述

2.6 补充:对于IDEA控制台乱码的解决方法

在这里插入图片描述

2.7 AES加密解密

  • AES 加密解密和 DES 加密解密代码一样,只需要修改加密算法就行
  • AES 加密的密钥key , 需要传入16个字节,否则,会出现以下错误信息
    java.security.InvalidKeyException: Invalid AES key length: 8 bytes
    
import org.junit.Test;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class DESTest {
    @Test
    public  void test() throws Exception {
        String input ="天下";
        // DES加密算法,key的大小必须是8个字节
        String key = "12345678";

        String transformation = "AES";
        // 指定获取密钥的算法
        String algorithm = "AES";
        String encryptDES = encryptDES(input, key, transformation, algorithm);
        System.out.println("加密:" + encryptDES);

        String s = decryptDES(encryptDES, key, transformation, algorithm);
        System.out.println("解密:" + s);

    }

    /**
     * 使用DES加密数据
     *
     * @param input          : 原文
     * @param key            : 密钥(DES,密钥的长度必须是8个字节)
     * @param transformation : 获取Cipher对象的算法
     * @param algorithm      : 获取密钥的算法
     * @return : 密文
     * @throws Exception
     */
    private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 获取加密对象
        Cipher cipher = Cipher.getInstance(transformation);
        // 创建加密规则
        // 第一个参数key的字节
        // 第二个参数表示加密算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // ENCRYPT_MODE:加密模式
        // 初始化加密模式和算法
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 加密
        byte[] bytes = cipher.doFinal(input.getBytes());

        // 输出加密后的数据
        String encode = Base64.encodeBase64String(bytes);

        return encode;
    }

    /**
     * 使用DES解密
     *
     * @param input          : 密文
     * @param key            : 密钥
     * @param transformation : 获取Cipher对象的算法
     * @param algorithm      : 获取密钥的算法
     * @throws Exception
     * @return: 原文
     */
    private static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 1,获取Cipher对象
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定密钥规则
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // DECRYPT_MODE: 解密模式
        cipher.init(Cipher.DECRYPT_MODE, sks);
        // 3. 解密,上面使用的base64编码,下面直接用密文
        byte[] bytes = cipher.doFinal(Base64.decodeBase64(input));
        //  因为是明文,所以直接返回
        return new String(bytes);
    }
}

在这里插入图片描述

2.8 补充: toString()与new String ()用法区别

public static void main(String[] args) {
        // 表示密文
        String str="TU0jV0xBTiNVYys5bEdiUjZlNU45aHJ0bTdDQStBPT0jNjQ2NDY1Njk4IzM5OTkwMDAwMzAwMA==";
        // 使用base64进行解码
        String rlt1=new String(Base64.decodeBase64(str.getBytes()));
        // 使用base64进行解码
        String rlt2= Base64.decodeBase64(str).toString();

        System.out.println("new String===" + rlt1);

        System.out.println("toString==" + rlt2);

    }

在这里插入图片描述

  • 哪一个是正确的?为什么?

  • new String()的方法,因为Base64加解密是一种转换编码格式的原理

  • toString()与new String ()用法区别

  • str.toString是调用了这个object对象的类的toString方法。一般是返回这么一个String:[class name]@[hashCode]

  • new String(str)是根据parameter是一个字节数组,使用java虚拟机默认的编码格式,将这个字节数组decode为对应的字符。若虚拟机默认的编码格式是ISO-8859-1,按照ascii编码表即可得到字节对应的字符。

  • 两个方法的使用时机:

  • new String()一般使用字符转码的时候,byte[]数组的时候

  • toString()对象打印的时候使用

2.9 加密模式

2.9.1 ECB

  • ECB : Electronic codebook, 电子密码本. 需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密
    在这里插入图片描述
  • 优点 : 可以并行处理数据
  • 缺点 : 同样的原文生成同样的密文, 不能很好的保护数据
  • 同时加密,原文是一样的,加密出来的密文也是一样的

2.9.2 CBC

  • CBC : Cipher-block chaining, 密码块链接. 每个明文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有明文块
    在这里插入图片描述
  • 优点 : 同样的原文生成的密文不一样
  • 缺点 : 串行处理数据.

2.10 填充模式

  • 当需要按块处理的数据, 数据长度不符合块处理需求时, 按照一定的方法填充满块长的规则

2.10.1 NoPadding

  • 不填充
  • 在DES加密算法下, 要求原文长度必须是8byte的整数倍
  • 在AES加密算法下, 要求原文长度必须是16byte的整数倍

2.10.2 PKCS5Padding

  • 数据块的大小为8位, 不够就补足

2.10.3 Tips

  • 默认情况下, 加密模式和填充模式为 : ECB/PKCS5Padding

  • 如果使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new IvParameterSpec(key.getBytes());

  • 加密模式和填充模式

    AES/CBC/NoPadding (128)
    AES/CBC/PKCS5Padding (128)
    AES/ECB/NoPadding (128)
    AES/ECB/PKCS5Padding (128)
    DES/CBC/NoPadding (56)
    DES/CBC/PKCS5Padding (56)
    DES/ECB/NoPadding (56)
    DES/ECB/PKCS5Padding (56)
    DESede/CBC/NoPadding (168)
    DESede/CBC/PKCS5Padding (168)
    DESede/ECB/NoPadding (168)
    DESede/ECB/PKCS5Padding (168)
    RSA/ECB/PKCS1Padding (1024, 2048)
    RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
    RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
    

2.11 加密模式和填充模式演示

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public static void main(String[] args) throws Exception{
        // 原文 如果使用的是不填充的模式,那么原文必须是8个字节的整数倍
        String input = "天下";
        // 定义key
        // 如果使用des进行加密,那么密钥必须是8个字节
        String key = "12345678";
        // ECB:表示加密模式
        // PKCS5Padding:表示填充模式 qANksk5lvqM=
        // 如果默认情况,没有写填充模式和加密模式,那么默认就使用DES/ECB/PKCS5Padding
        String transformation = "DES/CBC/PKCS5Padding";
        // 加密类型
        String algorithm = "DES";
        // 指定获取密钥的算法
        String encryptDES = encryptDES(input, key, transformation, algorithm);
        System.out.println("加密:" + encryptDES);

        String s = decryptDES(encryptDES, key, transformation, algorithm);
        System.out.println("解密:" + s);
    }

    /**
     * 解密
     * @param encryptDES  密文
     * @param key         密钥
     * @param transformation 加密算法
     * @param algorithm   加密类型
     * @return
     */
    private static String decryptDES(String encryptDES, String key, String transformation, String algorithm) throws Exception{
        Cipher cipher = Cipher.getInstance(transformation);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(),algorithm);
        // 创建iv向量
        IvParameterSpec iv = new IvParameterSpec(key.getBytes());
        //Cipher.DECRYPT_MODE:表示解密
        // 解密规则
        cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,iv);
        // 解密,传入密文
        byte[] bytes = cipher.doFinal(Base64.decodeBase64(encryptDES));

        return new String(bytes);
    }

    /**
     * 使用DES加密数据
     *
     * @param input          : 原文
     * @param key            : 密钥(DES,密钥的长度必须是8个字节)
     * @param transformation : 获取Cipher对象的算法
     * @param algorithm      : 获取密钥的算法
     * @return : 密文
     * @throws Exception
     */
    private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 获取加密对象
        Cipher cipher = Cipher.getInstance(transformation);
        // 创建加密规则
        // 第一个参数key的字节
        // 第二个参数表示加密算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // 创建iv向量,iv向量,是使用到CBC加密模式
        // 在使用iv向量进行加密的时候,iv的字节也必须是8个字节
        IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
        // ENCRYPT_MODE:加密模式
        // DECRYPT_MODE: 解密模式
        // 初始化加密模式和算法
        cipher.init(Cipher.ENCRYPT_MODE,sks,iv);
        // 加密
        byte[] bytes = cipher.doFinal(input.getBytes());

        // 输出加密后的数据
        String encode = Base64.encodeBase64String(bytes);

        return encode;
    }

在这里插入图片描述

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

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

相关文章

MySQL学习笔记第六天

第06章多表查询 5. 7种SQL JOINS的实现 A是员工表,B是部门表。 5.7.1 代码实现 #8. UNION 和 UNION ALL的使用 # UNION:会执行去重操作 # UNION ALL:不会执行去重操作,效率优于前者,开发中优先使用 #结论:如果明确…

【Java入门合集】第二章Java语言基础(四——第二章结束)

【Java入门合集】第二章Java语言基础(四——第二章结束) 博主:命运之光 专栏:JAVA入门 学习目标 掌握变量、常量、表达式的概念,数据类型及变量的定义方法; 掌握常用运算符的使用; 掌握程序的顺…

【LeetCode股票买卖系列:188. 买卖股票的最佳时机 IV | 暴力递归=>记忆化搜索=>动态规划】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

Hibernate(一)——入门

在之前经常用到操作数据库的框架是Mybatis或者Mybatis-plus。 Hibernate在項目中用过,但没有深入的了解过,所以这次趁着假期把这个框架了解一下。 目录 概念Hibernate和Mybatis的区别Hibernate使用依赖引入Hibernate配置文件XML配置文件详解properties文…

2023 年 五一杯 B 题过程 + 代码(第一问)

文章目录 第一题问题分析PageRank 算法(可跳过)PageRank 算法修正权重系数 结果各城市链出与链入链出 权重链入 权重 PageRank 算法结果代码 第一题 问题分析 从收货量、发货量、快递数量增长/减少趋势、相关性等多角度考虑,建立数学模型&…

如何使用git更新别人的代码

文章目录 如何使用git更新别人的代码问题说明省流问题示例操作步骤总结总结 如何使用git更新别人的代码 问题说明 当自己git clone别人的代码之后,代码一直停留到本地电脑上,而你就跑了一次程序就搁置了。 后来有一天你想再次运行该代码,但…

可观测性:你的应用健康吗?

一、需求来源 首先来看一下,整个需求的来源:当把应用迁移到 Kubernetes 之后,要如何去保障应用的健康与稳定呢?其实很简单,可以从两个方面来进行增强: 首先是提高应用的可观测性;第二是提高应…

Matplotlib 安装介绍

文章目录 安装步骤 Matplotlib 不止是一个数学绘图库,它也是可视化和分析工具中最流行之一。我们可用其制作简单的图表,如折线图和散点图。 安装步骤 先进入:python官网 跳转到界面: 录入并搜索 下载之前,看一下自…

嵌入式linux学习笔记--虚拟局域网组网方案分享,基于自组zerotier -planet 网络的方案

0. 前言 五一假期期间重新考虑了目前的组网环境,准备对目前的组网进行一个重新的划分。 目前有的资源 ① 两台 服务器,阿里云-深圳(5M上行)和腾讯云 广州(3M上行) ② 带动态公网IP的家庭宽带 (…

伽马校正的前世今生

关于伽马校正的前因后果,在网上有不同版本的说法,由于年代久远的因素,导致原本很简单的事情越说越复杂。今天我们的目标就是抓住伽马的头,而不是摸一下伽马的尾巴。 一,鱼龙混杂的论调 1,CRT 显示器的物理…

系统集成项目管理工程师下午真题 计算题 及考点 汇总(更新中。。。)

文章目录 2022下半年广东卷 2022下半年广东卷 1、质量保证、质量控制。质量管理方面存在的问题,并给出正确的做法。判断下列选项的正误。 2、下表是一个软件项目在编码阶段各活动的计划和实际完成情况(工作量,单位:人天&#xf…

Linux环境下的redis

一:安装与启动 1.下载redis安装包 2.解压:tar –xvf 文件名.tar.gz 3.安装 进入redis目录(cd redis-x.x.x/)后,执行make install 命令 4.启动 进入src目录,执行redis-server 此时该界面无法再使用,需要…

Eureka 服务注册源码探秘——图解、源码级解析

🍊 Java学习:社区快速通道 🍊 深入浅出RocketMQ设计思想:深入浅出RocketMQ设计思想 🍊 绝对不一样的职场干货:大厂最佳实践经验指南 📆 最近更新:2023年5月2日 🍊 点…

NPOI导出word文档中插入公式总结

1. XWPFOMath类 XWPFDocument doc new XWPFDocument(); //创建新行 XWPFParagraph p doc.CreateParagraph(); //创建空的公式 XWPFOMath math p.CreateOMath();通过XWPFParagraph的扩展方法创建 方法名备注CreateAcc();创建XWPFAcc类,实现字符在文字上面的类Cr…

【前端】2.HTML基础知识

文章目录 1. 基本概念1.1 HTML是什么1.2 HTML的作用1.3. 学习导引1.4 开发工具 2. HTML 基础语法2.1 demo2.1.1 HTML 详述2.1.2 HTML标签2.1.3 HTML网页结构2.1.4HTML版本 2.2 常用元素2.3 属性2.4 文本相关语法2.5 链接相关语法2.6 头部相关语法 3. 总结3.1 HTML 基础语法总结…

什么是VLAN?为什么要划分VLAN?

VLAN(Virtual Local Area Network)即虚拟局域网,是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。每个VLAN是一个广播域,VLAN内的主机间可以直接通信,而VLAN间则不能直接互通。这样,广播报文就被限制在一个VLAN内。 一、为…

如何简单快速搭建自己的云对象存储服务(OSS)

简单来说,其实我们只需要有一台服务器,利用服务器的各种资源,搭配其它厂商开发的软件,就能很轻易拥有自己的云对象存储服务。不需要在阿里云上花钱买什么服务,甚至还能自己给别人提供服务,真的是太爽了。 云…

五一创作【Android构建篇】MakeFile语法

前言 对于一个看不懂Makefile构建文件规则的人来说,这个Makefile语法和shell语法是真不一样,但是又引用了部分shell语法,可以说是shell语法的子类,Makefile语法继承了它。 和shell语法不一样,这个更难一点&#xff0…

云原生架构的发展历史

目录 1 单机小型机时代2 垂直拆分3 集群化负载均衡架构4 服务化改造架构5 服务治理6 微服务时代7 服务网格新时期 (service mesh)7.1 背景7.2 SideCar7.3 Linkerd7.4 istio7.5 什么是服务网格7.6 什么是Service Mesh7.7 CNCF云原生组织发展和介绍7.8 国内…

C++11--线程库的认识

目录 thread 线程的构造方式 相关成员函数 join与detach 线程传参 互斥量mutex mutex Locks 原子性操作库 条件变量 thread 线程的构造方式 它是不支持拷贝构造,赋值的,但是可以支持移动构造,移动赋值。还可以直接创建无参的对象。 …