对称加密加密原理和开发场景解析

简介: 加密是自古以来人们都在不断使用的技术,目的是为了隐藏信息,只是随着时代在不断的变化,加密也在不断的更新。从古代的藏宝图对藏宝地点进行隐藏。到二战时候,破译敌方电台,都是属于加密和破解的过程。进入21世纪后,加密在互联网时代也有了新的加密方法。也创造了密码学这个学科。目前在加密的场景下,通常分为:可逆加密和不可逆加密。而在可逆加密场景里又分为:对称加密和非对称加密。本次主要讨论集中在可逆加密上。可逆加密顾名思义就是在对明文进行加密后生成密文,能够通过解密把密文再还原成明文。数据加密一般主要解决三个问题:可信问题(非对称加密可解决),防篡改问题(不可逆加密解决),防窃听问题...

摘要

加密是自古以来人们都在不断使用的技术,目的是为了隐藏信息,只是随着时代在不断的变化,加密也在不断的更新。从古代的藏宝图对藏宝地点进行隐藏。到二战时候,破译敌方电台,都是属于加密和破解的过程。进入21世纪后,加密在互联网时代也有了新的加密方法。也创造了密码学这个学科。目前在加密的场景下,通常分为:可逆加密和不可逆加密。而在可逆加密场景里又分为:对称加密和非对称加密。本次主要讨论集中在可逆加密上。可逆加密顾名思义就是在对明文进行加密后生成密文,能够通过解密把密文再还原成明文。数据加密一般主要解决三个问题:可信问题(非对称加密可解决),防篡改问题(不可逆加密解决),防窃听问题(对称加密可解决,非对称部分可解决)。

对称加密

对称加密的原理就如字面意思所说,加密和解密的密钥是同一个。打个比喻就是:两个人开同一把锁,不分身份都可以用同一把钥匙打开锁。对称加密解决的最主要问题就是:防窃听问题。即在信息传输过程中,不能被第三方获取到信息的明文内容。

  • 优点:
  1. 加解密使用同一个密钥,比较方便。
  2. 加解密的速度快,适合大数据加密。
  • 缺点:
  • 密钥是信息接收和发送双方都在保存。对于密钥保存要求非常高。出现泄密的话,无法确定密钥泄露方。

对称加密算法简介

主流算法及优缺点

目前主流的对称加密算法有:DES,3DES,AES以及中国国密的SM4算法。

算法 优点 缺点
DES(Data Encrypt Standard) 数据标准加密:速度比较快,适合大数据量的数据加密。 速度快,但是安全性不够高
3DES 基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。 安全性低于AES
AES(Advanced Encryption Standard) 高级加密标准:是下一代加密算法标准,速度快,安全级别更高。可以使用128位,192位,256位的密钥。 -
SM4 中国自主设计,安全性同AES保持一致。由于自主设计,安全可控。 目前应用范围比较小。

AES算法

以AES加密为例来解释对称加密算法:
AES使用的密钥可以是:128位,192位和256位。不同长度的密钥带来的只有复杂度的区分。具体的加密过程分为:轮密钥加,字节代换,行位移,列混合。这四个操作全部操作一遍,为一轮加密。

  1. 轮密钥加:是将128位轮密钥Ki同状态矩阵中的数据进行逐位异或操作。
  2. 字节代换:AES的字符代换其实就是一个简单的查表操作,AES定义了一个S盒和一个逆S盒。
  3. 行位移:就是一个简单的左循环移位操作。
  4. 列混合:是通过矩阵相乘来实现的,经过移位后的状态矩阵与固定的矩阵相乘,得到混淆后的状态矩阵。

其中AES-128位会进行10轮的加密操作。每轮都包含这4个操作(第一轮和第十轮会稍有不同)。在进行循环加密结束后,生成的密文就可以进行传输使用了。这4个操作都是可逆操作,也就保证了解密的可行性。在解密的过程就是对这密文进行逆操作的过程。

轮密钥加

  • 轮密钥加

在这个步骤进行操作的时候,输入的内容是两个:明文和子密钥K[0](可以把k[0]当做密钥本身),这两个都是128bit的大小。两个输入内容按照矩阵排列,分别进行异或操作。其中明文使用P矩阵来表示,子密钥矩阵使用K矩阵。在进行异或操作后生成新的矩阵结果。
image.png

//这里对实际代码进行了一部分简化,方便理解。
void AddRoundKey(unsigned char(*P)[4], unsigned char(*K)[4])
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            P[i][j] ^= K[i][j];
        }
    }
}
//假设P矩阵如下,每个矩阵元素8bit, 0-255的范围.(无符号)
[2, @, 1, 0]
[a, 4, ^, 1]
[4, -, 1, )]
[9, a, c, .]
//K[0]矩阵如下
[%, *, a, 2]
[=, *, +, )]
[<, 2, #, 1]
[", *, d, ;]
则最后的加密结果矩阵是(16进制表示,因为有些字符是不可见字符):
[0x17, 0x6a, 0x50, 0x2]
[0x5c, 0x1e, 0x75, 0x18]
[0x8, 0x1f, 0x12, 0x18]
[0x1b, 0x4b, 0x7, 0x15]

字节代换

字节代换的操作比较简单,就是有一个S盒矩阵,将输入的字节,根据S盒矩阵,代换为另一个字节。这里的S盒矩阵是通过某种计算方法生成的,S盒矩阵大小为256,16行*16列。在映射的时候,把每个数据8bit的前4bit映射为行(4bit能表示的数字范围为0-15,刚好16),后4bit数据映射到列。进行数据代换。在解密的时候,有一个逆S盒,操作是一样的,叫做逆字节代换。

假设S盒如下:
image.png
逆S盒如下:
image.png
在上一轮的轮密钥加中我们得到矩阵:

[0x17, 0x6a, 0x50, 0x2]
[0x5c, 0x1e, 0x75, 0x18]
[0x8, 0x1f, 0x12, 0x18]
[0x1b, 0x4b, 0x7, 0x15]

我们先对矩阵第一个数据 0x17进行字节代换操作,根据S盒矩阵。如下图,得到0xF0
image.png
而得到的0xF0在逆S盒中,进行解密的逆字节代换可以发现又得到了0x17。
image.png

上一步的矩阵,逐个进行字节代换,得到最终的矩阵:

//S盒
const unsigned char S_Table[16][16] =
{
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};

//字节代换
int replaceSTable(unsigned char (*P)[4])
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; ++j)
        {
            P[i][j] = S_Table[P[i][j] >> 4][P[i][j] & 0x0F];
        }
    }
}
得到结果矩阵如下:
[0xF0, 0x02, 0x53, 0x77]
[0x4A, 0x72, 0x9D, 0xAD]
[0x30, 0xC0, 0xC9, 0xAD]
[0xAF, 0xB3, 0xC5, 0x59]

行位移

行位移是非常简单的操作,就是在一个4*4的矩阵上,对矩阵的行元素进行一次向左移动操作。而在AES中为何要加入这个如此简单的操作呢? 是因为这是为了下一步的列混合做准备,对矩阵的元素进行一次矩阵乘法,只要对矩阵的元素进行一次行位移,那么就会影响当前矩阵的状态,在下一步的列混合的时候,就会得到完全不一致的结果。达到一个雪崩效应的变化。
上一步骤得到的矩阵结果是:

[0xF0, 0x02, 0x53, 0x77] //不变
[0x4A, 0x72, 0x9D, 0xAD] //向左位移一个
[0x30, 0xC0, 0xC9, 0xAD] //向左位移两个
[0xAF, 0xB3, 0xC5, 0x59] //向左位移三个

void shiftRows(unsigned char *P[4]){
    unsigned char * tmp = (unsigned char *) malloc(sizeof(unsigned char) * 4);
    for (int i = 0 ; i < 4; i++) {
        for (int j = 0; j < i; j++) {
            tmp[j] = P[i][j];
        }
        for (int j = 0; j < 4 - i; j++) {
            P[i][j] = P[i][j+i];
        }
        for (int j = 4 - i; j < 4; j++) {
            P[i][j] = tmp[j+i-4];
        }
    }
    free(tmp);
}
//得到的结果数组为:
[0xf0 0x2 0x53 0x77]
[0x72 0x9d 0xad 0x4a]
[0xc9 0xad 0x30 0xc0]
[0x59 0xaf 0xb3 0xc5]

列混合

列混合是在这个加密逻辑中,比较复杂的操作,是通过将上一步行位移之后的结果,与一个给定的矩阵进行矩阵乘法。不过这个乘法,是在扩展域的乘法和加法。

//列混淆左乘矩阵
const unsigned char MixArray[4][4] =
{
0x02, 0x03, 0x01, 0x01,
0x01, 0x02, 0x03, 0x01,
0x01, 0x01, 0x02, 0x03,
0x03, 0x01, 0x01, 0x02
};

void MixColum(unsigned char(*PlainArray)[4])
{
    //定义变量
    unsigned char ArrayTemp[4][4];
    //初始化变量
    memcpy(ArrayTemp, PlainArray, 16);
    //矩阵乘法 4*4
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            PlainArray[i][j] =
            MixArray[i][0] * ArrayTemp[0][j] +
            MixArray[i][1] * ArrayTemp[1][j] +
            MixArray[i][2] * ArrayTemp[2][j] +
            MixArray[i][3] * ArrayTemp[3][j];
        }
    }
}

在扩展域内的加法等于异或运算,而在扩展域内的乘法就是伽罗瓦域乘法。对于伽罗瓦域乘法有兴趣的伽罗瓦域(有限域)
所以需要对这个矩阵乘法,进行伽罗瓦域乘法计算替换。这里不展开这个计算方法。对于逆列混合的时候,不是对矩阵做除法,而是使用逆矩阵,进行正向的乘法计算即可。

对称加密的开发场景应用

在实际的开发场景中,AES加密是用的最多的,第一是因为安全性是有公认的保障的,安全级别足够。第二是加密的速度比较快,作为数据加密算法合适。目前HTTPS的数据传输就是使用的AES加密。

使用场景

一般对称加密的主要应用场景是业务数据信息传输,防止消息被窃听。

  1. 对安全有极高要求的通讯软件。例如:军事领域,安全领域。
  2. 行业安全通信标准。例如:https。

可以简单概括为:只要是在网络中进行传输的数据,如果有防窃听的诉求,都需要对称加密的接入。

使用步骤

  1. 双方互换AES密钥。
  2. 密钥进行明文AES加密。
  3. 使用对方的AES密钥进行解密。

示例代码


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESCryptoUtil {

    /** AES密钥位数 */
    public static int SECRET_KEY_LENGTH = 128;

    /**
     * 生成AES密钥
     * 
     * @return
     * @throws NoSuchAlgorithmException
     * @throws IOException
     */
    public static byte[] getAutoCreateAESKey() throws NoSuchAlgorithmException {
        KeyGenerator kg = KeyGenerator.getInstance("AES");
        kg.init(128);//要生成多少位,只需要修改这里即可128, 192或256  
        SecretKey sk = kg.generateKey();
        byte[] skBuffer = sk.getEncoded();
        return skBuffer;
    }

    /**
     * 使用AES对称算法进行加密
     * 
     * @param secretKey
     * @param text
     * @return
     * @throws NoSuchPaddingException 
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeyException 
     * @throws UnsupportedEncodingException 
     * @throws BadPaddingException 
     * @throws IllegalBlockSizeException 
     */
    public static byte[] getAESEncode(byte[] secretKey,
                                      String text) throws NoSuchAlgorithmException,
                                                   NoSuchPaddingException, InvalidKeyException,
                                                   IllegalBlockSizeException, BadPaddingException,
                                                   UnsupportedEncodingException {
        SecretKeySpec sKeySpec = new SecretKeySpec(secretKey, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
        byte[] result = cipher.doFinal(text.getBytes("UTF-8"));
        return result;
    }

    /**
     * AES对称算法 解密
     * 
     * @param secretKey
     * @param text
     * @return
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws UnsupportedEncodingException
     */
    public static String getAESDecode(byte[] secretKey,
                                      byte[] text) throws NoSuchAlgorithmException,
                                                   NoSuchPaddingException, InvalidKeyException,
                                                   IllegalBlockSizeException, BadPaddingException,
                                                   UnsupportedEncodingException {
        SecretKeySpec sKeySpec = new SecretKeySpec(secretKey, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, sKeySpec);
        byte[] result = cipher.doFinal(text);
        return new String(result, "UTF-8");
    }

}

运算效率测试

AES加密

对长度500字节的内容进行加密1000次操作,耗时383毫秒。数据大小约为500KB。

public static void main(String[] args) {
        String content
            =
            "1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvw";
        String key = "1234567890abcdef";
        Long timer = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            encrypt(content, key);
        }
        System.out.println("time:" + (System.currentTimeMillis() - timer));
    }

image.png

AES解密

对生成的密文进行1000次解密,总共耗时344毫秒,大小同样为500KB。与加密性能基本一致。因为从上面的AES加解密步骤可以看到,其正向加密和逆向解密的复杂度是基本一模一样的。所以加解密的耗时基本一致,也在预料之中。

public static void main(String[] args) {
        String content
            =
            "1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvw";
        String key = "1234567890abcdef";
        Long timer = System.currentTimeMillis();
        String res = encrypt(content, key);

        for (int i = 0; i < 1000; i++) {
            decrypt(res, key);
        }
        System.out.println("time:" + (System.currentTimeMillis() - timer));
    }

image.png

交付场景思考

目前对称加密在交付项目上,可以对很多场景进行数据加密。例如:聊天沟通场景,用户A和用户B之间进行消息发送,文件发送,图片发送等等。都需要保证安全的话,就需要对消息进行加密传输。来保证就算被人中间窃取信息,也无法被获取信息。
但是这里有一个比较重要的问题是需要进行:密钥交换。如果保证在协商秘钥期间不会中间人给攻击,就涉及到了比较复杂的密钥交换环节。有感兴趣的可以看:DH密钥交换

目录
相关文章
|
4月前
|
Java 数据安全/隐私保护
对称加密、非对称加密与哈希摘要
本内容介绍了对称加密、非对称加密和哈希摘要的基本概念与区别。对称加密使用同一密钥加解密,速度快但需妥善保管密钥;非对称加密使用公钥加密、私钥解密,安全性高但速度较慢;哈希摘要通过提取数据特征用于完整性校验,能有效区分不同数据。
192 2
|
5月前
|
数据安全/隐私保护
解释对称加密、非对称加密、哈希摘要
加密技术分为对称加密与非对称加密。对称加密使用同一密钥进行加解密,速度快但需严保管密钥;非对称加密则用公钥加密、私钥解密,安全性高但速度较慢。哈希摘要用于验证数据完整性,代表原始数据特征。
179 0
|
5月前
|
存储 安全 数据处理
探讨对称加密与非对称加密的区别
综上所述,对称加密和非对称加密的选用取决于不同的安全需求、性能考量和应用情境。了解各自的特点和限制,才能有效地部署合理的加密策略,以确保数据通信的安全性和效率。
695 13
|
7月前
|
数据采集 监控 API
加密货币 Pump 监测刮刀工具开发原理及实现路径
开发Pump监测刮刀工具需综合运用高频数据采集、波动率建模、跨平台对冲三大核心技术,2025年的技术瓶颈已从基础数据获取转向超低延迟执行与合规适配。建议采用模块化开发策略,优先实现核心监控功能,再逐步接入AI决策与链上套利模块。代码示例需根据最新交易所API文档动态调整,并严格遵守所在地监管法规。
|
9月前
|
人工智能 API 开发者
HarmonyOS Next~鸿蒙应用框架开发实战:Ability Kit与Accessibility Kit深度解析
本书深入解析HarmonyOS应用框架开发,聚焦Ability Kit与Accessibility Kit两大核心组件。Ability Kit通过FA/PA双引擎架构实现跨设备协同,支持分布式能力开发;Accessibility Kit提供无障碍服务构建方案,优化用户体验。内容涵盖设计理念、实践案例、调试优化及未来演进方向,助力开发者打造高效、包容的分布式应用,体现HarmonyOS生态价值。
596 27
|
9月前
|
人工智能 API 语音技术
HarmonyOS Next~鸿蒙AI功能开发:Core Speech Kit与Core Vision Kit的技术解析与实践
本文深入解析鸿蒙操作系统(HarmonyOS)中的Core Speech Kit与Core Vision Kit,探讨其在AI功能开发中的核心能力与实践方法。Core Speech Kit聚焦语音交互,提供语音识别、合成等功能,支持多场景应用;Core Vision Kit专注视觉处理,涵盖人脸检测、OCR等技术。文章还分析了两者的协同应用及生态发展趋势,展望未来AI技术与鸿蒙系统结合带来的智能交互新阶段。
622 31
|
9月前
|
人工智能 小程序 前端开发
【一步步开发AI运动小程序】十九、运动识别中如何解析RGBA帧图片?
本文介绍了如何将相机抽取的RGBA帧图像解析为`.jpg`或`.png`格式,适用于体测、赛事等场景。首先讲解了RGBA图像结构,其为一维数组,每四个元素表示一个像素的颜色与透明度值。接着通过`uni.createOffscreenCanvas()`创建离屏画布以减少绘制干扰,并提供代码实现,将RGBA数据逐像素绘制到画布上生成图片。最后说明了为何不直接使用拍照API及图像转换的调用频率建议,强调应先暂存帧数据,运动结束后再进行转换和上传,以优化性能。
|
9月前
|
传感器 人工智能 监控
反向寻车系统怎么做?基本原理与系统组成解析
本文通过反向寻车系统的核心组成部分与技术分析,阐述反向寻车系统的工作原理,适用于适用于商场停车场、医院停车场及火车站停车场等。如需获取智慧停车场反向寻车技术方案前往文章最下方获取,如有项目合作及技术交流欢迎私信作者。
721 2
|
9月前
|
数据可视化 测试技术 API
前后端分离开发:如何高效调试API?有工具 vs 无工具全解析
在前后端分离的开发模式中,API 调试的效率直接影响项目的质量和交付速度。通过本文的对比分析,我们可以看到无工具调试模式虽具备灵活性和代码复用能力,但在操作便利性和团队协作上稍显不足。而传统的外部调试工具带来了可视化、高效协作与扩展性,却可能存在工具切换带来的开发链路断层问题。Apipost-Hepler 融合了两者的优势,让开发者无需离开熟悉的 IDEA 环境,就能享受可视化调试工具的强大功能。
313 5
|
9月前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

推荐镜像

更多
  • DNS