加密与安全_AES RSA 密钥对生成及PEM格式的代码实现

news2024/11/17 0:21:38

文章目录

  • RSA(非对称)和AES(对称)加密算法
    • 一、RSA(Rivest-Shamir-Adleman)
    • 二、AES(Advanced Encryption Standard)
  • RSA加密三种填充模式
    • 一、RSA填充模式
    • 二、常见的RSA填充模式组合
    • 三、选择合适的填充模式
    • 四、总结
  • AES的基本原理、工作模式、填充机制以及密钥和初始化向量(IV)的使用
    • 一、AES简介
    • 二、AES加密解密过程
    • 三、AES常见的工作模式
    • 四、AES填充模式
    • 五、AES密钥和初始化向量管理
  • RSA 生成 Code
    • 一、Java中的RSA加密实现
    • 二、选择合适的密钥长度
    • 三、密钥的管理和存储
      • Code: 将密钥转换为PEM格式
    • 四、总结

在这里插入图片描述


RSA(非对称)和AES(对称)加密算法

在现代信息安全中,加密算法扮演着至关重要的角色。今天我们来聊聊两种常见的加密算法——RSA和AES,用通俗易懂的语言带大家理解它们的核心原理和优缺点。

一、RSA(Rivest-Shamir-Adleman)

核心原理:
RSA是一种非对称加密算法,这意味着它使用一对密钥:公钥和私钥。通俗来说,公钥可以公开,用来加密信息;而私钥需要保密,用来解密信息。它的安全性主要依赖于一个数学难题:大整数的质因数分解。具体步骤如下:

  1. 选择质数:选择两个大质数p和q。
  2. 计算乘积:计算p和q的乘积n = p * q,这就是公钥的一部分。
  3. 计算欧拉函数:计算欧拉函数φ(n) = (p-1)*(q-1)。
  4. 选择公钥指数:选择一个小于φ(n)的整数e,且e与φ(n)互质,这就是公钥的另一部分。
  5. 计算私钥指数:计算e对于φ(n)的模反元素d,这就是私钥。

优点:

  • 安全性高:由于大整数的质因数分解非常困难,破解RSA几乎不可能。
  • 公钥加密:公钥可以公开分享,方便信息的安全传输。

缺点:

  • 速度慢:加密和解密过程计算复杂,速度较慢。
  • 密钥长度大:需要较长的密钥(通常为2048位或以上)来保证安全性,存储和处理成本高。

二、AES(Advanced Encryption Standard)

核心原理:
AES是一种对称加密算法,这意味着它使用同一个密钥进行加密和解密。它基于一种叫做“分组密码”的方法,把数据分成固定大小的块(通常是128位),然后通过多个轮次的处理来加密数据。每轮处理包括以下步骤:

  1. 替代(Substitution):使用预先定义的S盒对数据进行替换。
  2. 换位(Permutation):重新排列数据的顺序。
  3. 混淆(Mixing):对数据进行复杂的数学运算混合。
  4. 轮密钥加(Add Round Key):与轮密钥进行异或运算。

优点:

  • 速度快:由于AES算法的设计简单且高效,处理速度快,适合大数据量的加密。
  • 安全性高:AES算法在多年的使用中,未被成功破解,具有很高的安全性。

缺点:

  • 密钥管理复杂:对称加密要求通信双方事先共享同一个密钥,密钥的分发和管理较为复杂。
  • 密钥泄露风险:一旦密钥泄露,所有加密的数据都会暴露,因此密钥保护非常重要。

RSA和AES是现代密码学中两种重要的加密算法,各有优缺点。RSA依赖于复杂的数学难题,安全性高但速度较慢;AES则以其高效的加密速度和广泛应用而著称,但在密钥管理上存在挑战。


RSA加密三种填充模式

RSA加密算法在实际应用中常常使用填充模式来确保数据的安全性和算法的有效性。

填充模式是为了使加密数据和公钥长度一致,并增加加密的安全性。

接下来我们看下主要的RSA填充模式:ENCRYPTION_OAEPENCRYPTION_PKCS1ENCRYPTION_NONE,以及常见的填充模式组合。

一、RSA填充模式

1. ENCRYPTION_OAEP(Optimal Asymmetric Encryption Padding)

  • 简介:OAEP是目前最安全的RSA填充模式,广泛推荐用于现代加密应用中。
  • 原理:OAEP在加密数据前,先通过一个哈希函数和一个掩码生成函数(MGF)对数据进行填充,确保每次加密的结果都不同,即使相同的数据和密钥也不会产生相同的密文。
  • 优点:高安全性,防止多种已知攻击(如选择密文攻击)。
  • 使用场景:需要高度安全性的数据加密和解密操作。

2. ENCRYPTION_PKCS1(PKCS #1 v1.5 Padding)

  • 简介:PKCS1是RSA加密最常用的填充模式之一,因其随机填充的特性,确保相同数据每次加密结果不同。
  • 原理:PKCS1填充在数据前面添加一个随机填充字符串,并确保数据长度和密钥长度一致。
  • 优点:较为简单,已经广泛使用和支持。
  • 缺点:相对于OAEP,安全性略低,可能受到一定类型的攻击(如选择密文攻击)。
  • 使用场景:一般数据加密,广泛应用于SSL/TLS协议中。

3. ENCRYPTION_NONE(No Padding)

  • 简介:无填充模式,直接对数据进行加密。
  • 原理:数据长度必须与密钥长度相同,不进行任何额外的填充处理。
  • 优点:实现简单。
  • 缺点:安全性较低,易受各种攻击,不推荐使用。
  • 使用场景:通常仅在特定条件下或内部使用。

二、常见的RSA填充模式组合

1. RSA/None/PKCS1Padding

  • 简介:该模式表示没有指定具体的块加密模式(None),使用PKCS1填充。
  • 特点:确保相同数据每次加密结果不同,适用于许多常见的加密场景。

2. RSA/ECB/PKCS1Padding

  • 简介:该模式表示使用电子密码本(ECB)模式进行加密,并使用PKCS1填充。
  • 特点:在每个块中独立加密,但ECB模式本身不推荐用于大数据量的加密,因为相同的明文块会被加密成相同的密文块,这可能导致模式泄露问题。
  • 适用场景:一般数据加密,广泛应用于加密协议中。

三、选择合适的填充模式

选择合适的填充模式需要根据具体应用场景来考虑:

  1. 高安全性需求:推荐使用ENCRYPTION_OAEP填充模式,尤其是在敏感数据的加密和解密中。
  2. 广泛兼容性:ENCRYPTION_PKCS1是一个较好的选择,已经被广泛支持和使用,适用于大多数应用场景。
  3. 实验性或内部使用:ENCRYPTION_NONE模式仅在特定情况下使用,需确保其他安全措施到位。

四、总结

RSA加密算法的填充模式是确保数据安全性和算法有效性的关键。ENCRYPTION_OAEP、ENCRYPTION_PKCS1和ENCRYPTION_NONE各有优缺点和适用场景。在实际应用中,根据具体需求选择合适的填充模式,能够有效提升加密的安全性和性能。


AES的基本原理、工作模式、填充机制以及密钥和初始化向量(IV)的使用

AES(Advanced Encryption Standard)是一种广泛使用的对称加密算法,旨在替代原先的DES和3DES。AES凭借其高效的加密速度和强大的安全性,成为现代数据加密的首选。

接下来我们来看下AES的基本原理、工作模式、填充机制以及密钥和初始化向量(IV)的使用。

一、AES简介

主要特点:

  • 对称加密:同一个密钥用于加密和解密。
  • 块加密:以固定大小的块(128位)对数据进行加密。
  • 高效性:比公钥加密算法快很多,适用于需要高性能的数据加密场景。

主要缺点:

  • 密钥管理:需要加密端和解密端都使用相同的密钥,密钥分发和管理较为复杂。

二、AES加密解密过程

AES加密需要:

  • 明文:需要加密的数据。
  • 密钥(Key):用于加密和解密的密钥,长度可以是128位、192位或256位。
  • 偏移量(IV):初始化向量,用于将加密随机化,提高安全性。
  • 密码模式:算法/模式/填充,如AES/CBC/PKCS5Padding。

AES解密需要:

  • 密文:已加密的数据。
  • 密钥(Key):与加密时使用的密钥相同。
  • 偏移量(IV):与加密时使用的初始化向量相同。
  • 密码模式:算法/模式/填充,如AES/CBC/PKCS5Padding。

三、AES常见的工作模式

1. 电码本模式(ECB)

  • 特点:每个数据块独立加密,相同的明文块会被加密成相同的密文块。
  • 优点:实现简单,不需要初始化向量。
  • 缺点:不安全,容易受到模式泄露攻击。
  • 使用场景:不推荐在安全需求高的场景下使用。

2. 密码分组链接模式(CBC)

  • 特点:每个明文块与前一个密文块进行异或运算后再加密,第一个块需要初始化向量(IV)。
  • 优点:安全性高,每个块的加密结果都不同。
  • 使用场景:广泛用于文件加密和数据传输加密。

3. 计算器模式(CTR)

  • 特点:将一个计数器的输出与明文块进行异或运算,实现加密。
  • 优点:可并行处理,提高加密速度。
  • 使用场景:适用于流式数据加密和高性能需求的场景。

4. 密码反馈模式(CFB)

  • 特点:前一个密文块作为下一块的输入,结合初始化向量(IV)提高安全性。
  • 优点:适用于需要逐字节或逐位加密的场景。
  • 使用场景:实时数据加密,如网络数据流。

5. 输出反馈模式(OFB)

  • 特点:将初始化向量与密钥结合,通过反馈机制生成加密序列。
  • 优点:加密过程独立于明文块的内容。
  • 使用场景:适用于逐位加密和需要抗噪声的场景。

四、AES填充模式

填充模式的必要性:
由于AES是一种块加密算法,处理的数据块必须是固定长度(128位),因此需要填充模式来确保数据长度符合要求。

常见填充模式:

  • PKCS7:在数据末尾添加一系列字节,每个字节的值表示填充的字节数,广泛使用,兼容性好。
  • None:不进行填充,要求输入数据的长度必须是块长度的整数倍。

五、AES密钥和初始化向量管理

密钥(Key):

  • AES标准规定的密钥长度为128位、192位和256位,分别对应16字节、24字节和32字节。
  • 密钥不能公开传输,需要安全地管理和保护。

初始化向量(IV):

  • IV用于将加密随机化,确保相同的明文被多次加密产生不同的密文。
  • IV可以公开,但不能重复使用。推荐每次加密时生成一个新的16字节随机值。
  • 在加密端将IV和密文一起发送给解密端,确保解密端能够正确还原数据。

RSA 生成 Code

RSA加密算法在Java中有多种实现方式,其中默认的实现方式是RSA/None/PKCS1Padding。在实际应用中,为了确保安全性和兼容性,需要注意密钥长度、密钥格式以及密钥管理。

一、Java中的RSA加密实现

默认实现:RSA/None/PKCS1Padding

  • RSA:表示使用RSA算法进行加密。
  • None:没有指定具体的块加密模式。
  • PKCS1Padding:使用PKCS#1 v1.5填充模式,这是常见的RSA填充方式。

为什么选择PKCS1Padding?

PKCS1Padding是一种较为常用且广泛支持的填充方式,它通过添加随机填充数据,确保相同的数据每次加密结果不同,从而提高安全性。

二、选择合适的密钥长度

推荐使用2048位或更长的密钥

  • 1024位密钥:在现代计算能力下已经不再安全,容易受到攻击。
  • 2048位或更长的密钥:提供更高的安全性,推荐使用2048位或4096位的密钥,以应对未来更强的攻击手段。

创建RSA密钥对

 package com.artisan.jasypt.rsa;

import java.io.UnsupportedEncodingException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;

/**
 * @author 小工匠
 * @version 1.0
 * @mark: show me the code , change the world
 */
public class RsaTest {

    /**
     * 主程序入口,用于演示如何生成和打印RSA密钥对的公钥和私钥。
     *
     * @param args 命令行参数(未使用)
     * @throws UnsupportedEncodingException 如果编码不被支持
     */
    public static void main(String[] args) throws UnsupportedEncodingException {

        // 生成2048位的RSA密钥对
        KeyPair keyPair = getKeyPair(2048);
        // 获取公钥
        byte[] publicKey = getPublicKey(keyPair);
        // 获取私钥
        byte[] privateKey = getPrivateKey(keyPair);

        // 打印编码后的公钥和私钥
        System.out.println("Private Key: " + Base64.getEncoder().encodeToString(publicKey));
        System.out.println("Public Key: " + Base64.getEncoder().encodeToString(privateKey));
    }


    /**
     * 生成RSA算法的密钥对
     * @param keyLength 密钥长度,用于初始化密钥生成器
     * @return 生成的密钥对,包含公钥和私钥
     */
    public static KeyPair getKeyPair(int keyLength) {
        try {
            // 实例化密钥对生成器,并指定算法为RSA
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            // 初始化密钥对生成器,设置密钥长度
            keyPairGenerator.initialize(keyLength);
            // 生成密钥对
            return keyPairGenerator.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            // 当指定的加密算法不可用时,抛出运行时异常
            throw new RuntimeException("生成密钥对时遇到异常" +  e.getMessage());
        }
    }


    /**
     * 获取公钥
     *
     * @param keyPair 包含公钥和私钥的密钥对
     * @return 公钥的字节数组形式
     */
    public static byte[] getPublicKey(KeyPair keyPair) {
        // 将密钥对中的公钥转换为RSAPublicKey类型
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        // 获取并返回公钥的编码形式
        return rsaPublicKey.getEncoded();
    }


    /**
     * 获取私钥
     *
     * @param keyPair 包含公钥和私钥的密钥对
     * @return 返回私钥的字节数组形式
     */
    public static byte[] getPrivateKey(KeyPair keyPair) {
        // 将keyPair中的私钥转换为RSAPrivateKey类型
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        // 返回私钥的编码形式
        return rsaPrivateKey.getEncoded();
    }

}
    
 package com.artisan.jasypt.rsa;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;

/**
 * @author 小工匠
 * @version 1.0
 * @mark: show me the code , change the world
 */
public class RSAKeyPairGenerator {
    /**
     * 主函数用于生成RSA算法的密钥对,并打印出其Base64编码的字符串形式。
     *
     * @param args 命令行参数(未使用)
     * @throws NoSuchAlgorithmException 如果指定的加密算法不可用,则抛出此异常。
     */
    public static void main(String[] args) throws NoSuchAlgorithmException {
        // 创建RSA算法的密钥对生成器
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");

        // 初始化密钥对生成器,设置密钥长度为2048位
        keyPairGen.initialize(2048);

        // 生成密钥对
        KeyPair pair = keyPairGen.generateKeyPair();

        // 从密钥对中提取私钥和公钥
        PrivateKey privateKey = pair.getPrivate();
        PublicKey publicKey = pair.getPublic();

        // 打印出私钥和公钥的Base64编码
        System.out.println("Private Key: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));
        System.out.println("Public Key: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));
    }

}

三、密钥的管理和存储

密钥生成与存储的流程

  • 服务器创建密钥对:服务器负责生成RSA密钥对,确保私钥的安全存储。
  • 公钥下发至客户端:将公钥分发给需要加密数据的客户端。
  • 私钥保存在服务器:私钥必须保密,通常存储在服务器上,确保其不被泄露。

密钥格式:DER和PEM

  • DER(Distinguished Encoding Rules):二进制格式,主要用于机器处理,不便于阅读。
  • PEM(Privacy-Enhanced Mail):将DER格式通过Base64编码转换为字符格式,更易于阅读和传输。

PEM格式的密钥示例

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr8p1oxcLljRG/Qffkh6N
...
-----END PUBLIC KEY-----

-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCr8p1oxcLljRG/
...
-----END PRIVATE KEY-----

Code: 将密钥转换为PEM格式

 package com.artisan.jasypt.rsa;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
/**
 * @author 小工匠
 * @version 1.0
 * @mark: show me the code , change the world
 */
public class KeyToPEM {

    /**
     * 主函数:生成RSA密钥对,并将其转换为PEM格式输出。
     *
     * @param args 命令行参数(未使用)
     * @throws Exception 如果密钥生成或转换过程中发生错误
     */
    public static void main(String[] args) throws Exception {
        // 生成RSA密钥对,使用2048位长度
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        KeyPair keyPair = keyGen.generateKeyPair();

        // 提取公钥和私钥
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 将公钥和私钥转换为PEM格式
        String publicKeyPEM = convertToPEMFormat(publicKey.getEncoded(), "PUBLIC KEY");
        String privateKeyPEM = convertToPEMFormat(privateKey.getEncoded(), "PRIVATE KEY");

        // 输出转换后的PEM格式公钥和私钥
        System.out.println(publicKeyPEM);
        System.out.println(privateKeyPEM);
    }


    /**
     * 将密钥字节数组转换为PEM格式的字符串。
     * PEM(Privacy Enhanced Mail)格式是一种常见的密钥存储格式,以 base64 编码的密钥数据为主要内容,并以“-----BEGIN”和“-----END”为标记。
     *
     * @param key 密钥的字节数组。
     * @param keyType 密钥的类型(如RSA PRIVATE KEY等)。
     * @return 转换后的PEM格式密钥字符串。
     */
    public static String convertToPEMFormat(byte[] key, String keyType) {
        // 将密钥字节数组转换为Base64编码的字符串
        String base64EncodedKey = Base64.getEncoder().encodeToString(key);
        StringBuilder pemKey = new StringBuilder();

        // 添加PEM格式的起始标记
        pemKey.append("-----BEGIN ").append(keyType).append("-----\n");

        // 将Base64编码的密钥拆分为64字符一组,并添加换行符
        for (int i = 0; i < base64EncodedKey.length(); i += 64) {
            pemKey.append(base64EncodedKey, i, Math.min(i + 64, base64EncodedKey.length())).append("\n");
        }

        // 添加PEM格式的结束标记
        pemKey.append("-----END ").append(keyType).append("-----");

        return pemKey.toString();
    }
}
    

四、总结

RSA加密在Java中的默认实现是RSA/None/PKCS1Padding,推荐使用2048位或更长的密钥以确保安全。密钥管理是保证加密系统安全的重要环节,私钥应保存在服务器上,公钥分发给客户端。PEM格式的密钥更易于阅读和传输,通常用于存储和交换密钥。

在这里插入图片描述

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

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

相关文章

Python小游戏——俄罗斯方块

文章目录 项目介绍环境配置代码设计思路1.初始化和导入库&#xff1a;2.定义颜色和屏幕尺寸&#xff1a;3.定义游戏逻辑&#xff1a;4.游戏循环&#xff1a; 源代码效果图 项目介绍 俄罗斯方块游戏是一款经典的益智游戏&#xff0c;玩家通过旋转和移动各种形状的方块&#xff…

页面<html>上多了一个滚动条,定位发现是<body>里面多了一个id为trans-tooltip的div

现象分析&#xff1a; 页面根标签html多了一个滚动条&#xff0c;发现body里面多了一个id为trans-tooltip的div&#xff0c;虽然width为0&#xff0c;height为0&#xff0c;但是其子元素还是有高度&#xff0c;占据了空间&#xff0c;最终导致了滚动条&#xff1b; 根本原因&…

怎么在pyqt中显示matplotlib的绘图?

想要在pyqt中显示matplotlib的绘图&#xff0c;在绘图时&#xff0c;其实不必使用以下语句&#xff1a; matplotlib.use("Qt5Agg") # 声明使用QT5最关键的语句是&#xff1a; from matplotlib.backends.backend_qt5agg import FigureCanvasQTAggFigureCanvasQTAgg…

Selenium 自动化测试工具<2>(Selenium 常用API的使用方法)

文章目录 浏览器操作浏览器最大化设置浏览器的大小浏览器的前进和后退操作浏览器滚动条 键盘事件单个按键用法键盘组合键用法 鼠标事件不同窗口搜索定位一组元素定位多层框架下拉框定位alert、confirm、prompt 的处理上传文件操作自动截屏 继上一篇文章对 Selenium API 的使用&…

HTML蓝色爱心

目录 写在前面 HTML入门 完整代码 代码分析 运行结果 系列推荐 写在后面 写在前面 最近好冷吖&#xff0c;小编给大家准备了一个超级炫酷的爱心&#xff0c;一起来看看吧&#xff01; HTML入门 HTML全称为HyperText Markup Language&#xff0c;是一种标记语言&#…

Linux(六)

Linux&#xff08;六&#xff09; 自定义头文件自定义头文件中写什么如何引入头文件条件编译条件编译作用 gcc工作原理Make 工作管理器什么是Make什么是Makefile/makefileMakefile假目标Makefile中的变量自定义变量预定义变量自动变量 Makefile中变量展开方式递归展开方式简单展…

【Python】 如何使用.whl文件安装Python包?

基本原理 在Python的世界中&#xff0c;.whl文件是一种分发格式&#xff0c;它代表“Wheel”。Wheel是一种Python包格式&#xff0c;旨在提供一种快速、可靠且兼容的方式&#xff0c;用于安装Python库。与源代码包相比&#xff0c;Wheel文件是预编译的&#xff0c;这意味着它们…

【2024.5.26 软件设计师】记录第一次参加软考(附资料)

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎 ❤️关注 &#x1f44d;点赞 &#x1f64c;收藏 ✍️留言 文章目录 前言考试分析选择题案例分析题话外 软考总结资料 前言 这是我第一次参加软考&#xff0c;其实我并…

家乡特色|基于SprinBoot+vue的家乡特色推荐系统(源码+数据库+文档)

家乡特色推荐系统 目录 基于SprinBootvue的家乡特色推荐系统 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&…

京东Java社招面试题真题,最新面试题

Java中接口与抽象类的区别是什么&#xff1f; 1、定义方式&#xff1a; 接口是完全抽象的&#xff0c;只能定义抽象方法和常量&#xff0c;不能有实现&#xff1b;而抽象类可以有抽象方法和具体实现的方法&#xff0c;也可以定义成员变量。 2、实现与继承&#xff1a; 一个类…

SELINUX=enforcing时无法启动httpd服务的解决方案(semanage命令以及setroubleshoot-server插件的妙用)

一、问题描述&#xff1a; 当/etc/selinux/conf被要求必须是SELINUXenforcing&#xff0c;不被允许使用setenforce 0宽松模式 我们启动httpd就会报错&#xff1a; Job for httpd.service failed because the control process exited with error code. See "systemctl s…

STM32-GPIO八种输入输出模式

图片取自 江协科技 STM32入门教程-2023版 细致讲解 中文字幕 p5 【STM32入门教程-2023版 细致讲解 中文字幕】 https://www.bilibili.com/video/BV1th411z7sn/?p5&share_sourcecopy_web&vd_source327265f5c70f26411a53a9226af0b35c 目录 ​编辑 一.STM32的四种输…

excel表格写存神器--xlwt

原文链接&#xff1a;http://www.juzicode.com/python-tutorial-xlwt-excel 在 Python进阶教程m2d–xlrd读excel 中我们介绍了Excel表格的读取模块xlrd&#xff0c;今天这篇文章带大家了解Excel表格写存模块xlwt。他俩名字相近都以Excel的简写xl开头&#xff0c;rd是read的简写…

Elasticsearch的Index sorting 索引预排序会导致索引数据的移动吗?

索引预排序可以确保索引数据按照指定字段的指定顺序进行存储&#xff0c;这样在查询的时候&#xff0c;如果固定使用这个字段进行排序就可以加快查询效率。 我们知道数据写入的过程中&#xff0c;如果需要确保数据有序&#xff0c;可能需要在原数据的基础上插入新的数据&#…

slint esp32 tokio

源码&#xff1a;https://github.com/xiaguangbo/slint_esp32_tokio cpu 是 esp32c2&#xff0c;屏幕是 ili9341&#xff0c;触摸是 xpt2046&#xff0c;使用 spi 半双工 不使用DMA&#xff08;esp-rs还没支持&#xff09;&#xff0c;SPI 40M&#xff0c;240*320全屏刷新为1.5…

HTTP交互导致ECONNABORTED的原因之一

背景&#xff1a; 本次记录的&#xff0c;是一次使用HTTP交互过程中遇到的问题&#xff0c;问题不大&#xff0c;就是给题目上这个报错补充一种可能的解决方案。 程序大致流程&#xff1a; 1. 设备向服务器A请求信息 2. 拿到回复记录下回复内容中的数据包下载地址等信息 3…

sql聚合函数使用-笔记

sql聚合函数使用-笔记 SELECT SUM ( case when procurement_type 公益推送 then 1 else 0 end ) gywxTotal,SUM ( CASE WHEN (status 1 and procurement_type 公益推送) THEN 1 ELSE 0 END ) gywxYsc,SUM ( CASE WHEN (status ! 1 and procurement_type 公益推送) THEN 1 …

k8s部署presto

&#xff08;作者&#xff1a;陈玓玏&#xff09; 一、前提条件 已部署k8s&#xff1b;已部署hadoop和hive&#xff0c;可参考以下链接&#xff1a; https://blog.csdn.net/weixin_39750084/article/details/136750613?spm1001.2014.3001.5502 https://blog.csdn.net/wei…