当前位置: 首页 > news >正文

3步打造C# API安全密盾

引言:API 安全的重要性

在数字化浪潮中,应用程序编程接口(API)已成为不同软件系统之间通信和数据交互的关键桥梁。无论是企业内部的微服务架构,还是面向外部用户的在线服务,API 都承担着数据传输和业务逻辑执行的重任。据相关数据显示,如今大部分互联网流量(71%)都是 API 调用 ,这充分凸显了 API 在现代互联网架构中的核心地位。

但随着 API 的广泛应用,其安全问题也日益凸显。API 作为访问敏感数据的直接途径,一旦遭受攻击,后果不堪设想。数据泄露可能导致用户个人信息、商业机密等重要数据被窃取,给企业和用户带来巨大的损失;身份验证失败可能让攻击者绕过权限控制,非法访问受限资源;中间人攻击则可能篡改传输数据,破坏数据的完整性和真实性;注入攻击、DDoS 攻击等也会对系统的稳定性和可用性造成严重威胁。根据 Fastly 的一项调查,95% 的企业在过去 1 年中遇到过 API 安全问题 ,而 Marsh McLennan 的研究表明,与 API 相关的安全事件每年给全球企业造成的损失高达 750 亿美元 。这些惊人的数据警示着我们,API 安全已成为保障数据安全和业务流程正常运行的关键环节。

C# 作为一种强大的编程语言,在构建安全可靠的 API 方面具有显著优势。它依托于丰富的.NET 框架,为开发者提供了一套全面且易用的加密和安全相关的类库,如 System.Security.Cryptography 命名空间,涵盖了从对称加密、非对称加密到哈希函数等多种常用的安全机制,能够满足不同场景下的安全需求。接下来,我们就深入探讨如何利用 C# 的这些特性,分三步打造坚不可摧的 API 安全密盾。

第一步:加密前的密谋 —— 了解基础

(一)加密概念介绍

在深入探讨如何使用 C# 构建 API 安全防护体系之前,我们需要先熟悉几种常见的加密概念及其特性,它们是构建安全密盾的基石。

对称加密,就像一把钥匙开一把锁,加密和解密过程使用的是同一个密钥。这种加密方式的显著优势在于加密和解密的速度极快,能够高效地处理大量数据。例如,在一些对数据处理速度要求较高的场景中,如实时数据传输、大规模数据存储加密等,对称加密能够迅速完成加密和解密操作,确保数据的快速流转。但它也存在一个明显的短板,那就是密钥的管理难度较大。由于加密和解密使用相同的密钥,在数据传输之前,发送方和接收方必须通过安全的方式商定并妥善保存这个密钥。一旦密钥在传输过程中被窃取,整个加密体系就会面临被攻破的风险 。常见的对称加密算法有 AES(Advanced Encryption Standard)、DES(Data Encryption Standard)等,其中 AES 以其出色的安全性和性能,成为了目前应用最为广泛的对称加密算法之一 。

非对称加密则引入了一对密钥:公钥和私钥。公钥可以公开分发,任何人都可以使用它来加密消息;而私钥则由持有者妥善保管,只有私钥的拥有者才能用它来解密使用对应公钥加密的消息。这种加密方式的安全性极高,因为从公钥几乎无法推断出私钥,即使攻击者获取了公钥和密文,也难以破解出原始数据。它常用于数字签名、身份验证等场景,比如在电子合同签署过程中,使用非对称加密可以确保签名的不可伪造性和消息的完整性。然而,非对称加密的加密和解密过程涉及复杂的数学运算,速度相对较慢,在处理大量数据时效率较低 。典型的非对称加密算法有 RSA(Rivest-Shamir-Adleman)、ECC(Elliptic Curve Cryptography)等 。

哈希(Hash)是一种单向的摘要算法,它能将任意长度的输入数据转换为固定长度的哈希值。哈希的主要特点是不可逆性,即无法从哈希值反向推导出原始数据。它常用于验证数据的完整性,比如在文件传输过程中,发送方计算文件的哈希值并一同发送,接收方在收到文件后重新计算哈希值,若两者一致,则说明文件在传输过程中未被篡改。但哈希并不适合直接用于加密通信,因为它无法提供保密性,任何人都可以计算出相同数据的哈希值 。常见的哈希算法有 SHA-256(Secure Hash Algorithm 256-bit)、MD5(Message-Digest Algorithm 5)等,不过由于 MD5 存在碰撞风险,安全性逐渐受到质疑,在安全要求较高的场景中已逐渐被 SHA-256 等更安全的算法所取代 。

(二)混合加密策略原理

在 API 加密的实际应用中,单一的加密方式往往难以满足复杂的安全需求,因此我们通常采用混合加密策略,将对称加密和非对称加密的优势结合起来。

具体来说,对称加密用于保护数据主体,因为它的加密速度快,能够高效地处理大量的数据传输,确保 API 的性能不受太大影响。例如,在 API 请求和响应中,对包含敏感信息的主体数据进行对称加密,使得即使数据在传输过程中被截获,攻击者也难以直接获取其中的内容。

而非对称加密则用于保护对称加密所使用的密钥。由于对称加密的密钥管理是一个难题,通过非对称加密,我们可以使用接收方的公钥对对称加密的密钥进行加密传输。这样,只有拥有对应私钥的接收方才能解密得到对称密钥,从而保证了对称密钥在传输过程中的安全性。

以一个简单的 API 数据传输场景为例,客户端生成一个随机的对称密钥,使用该密钥对要发送给服务器的数据进行对称加密,得到密文数据。然后,客户端使用服务器的公钥对这个对称密钥进行非对称加密,得到加密后的密钥。在传输时,将密文数据和加密后的密钥一同发送给服务器。服务器收到后,首先使用自己的私钥解密得到对称密钥,再用这个对称密钥解密密文数据,从而获取到原始的明文数据。

这种混合加密策略既利用了对称加密的高效性,又借助了非对称加密的高安全性,实现了安全与性能的平衡,是保障 API 数据安全传输的常用且有效的手段 。

第二步:C# 加密实战 —— 走起!

(一)准备阶段:引入帮手

在 C# 项目中,我们首先要引入加密相关的命名空间,这些命名空间就像是我们打造安全密盾的得力工具。主要涉及System.Security.Cryptography和System.Text。System.Security.Cryptography命名空间是加密的核心库,它提供了丰富的加密算法和工具类,涵盖了对称加密、非对称加密、哈希算法等各种加密机制,是实现数据加密和解密的关键所在 。而System.Text命名空间则用于字符串处理,在加密过程中,我们经常需要将字符串转换为字节数组进行处理,或者将加密后的字节数组再转换回字符串形式,System.Text命名空间中的类和方法为这些操作提供了便利 。

引入这两个命名空间的代码如下:

using System.Security.Cryptography; // 加密核心库
using System.Text; // 字符串处理

通过引入这两个命名空间,我们的项目就具备了使用各种加密算法和进行字符串处理的能力,为后续的加密实战奠定了基础。

(二)对称加密:AES 的秘密

在了解了加密的基本概念和准备好必要的工具后,我们开始使用 AES 进行对称加密的实战。AES(Advanced Encryption Standard)是一种被广泛应用的对称加密算法,以其安全性高、速度快等优点,成为了保护数据主体的首选算法之一 。

  1. 代码实现

以下是使用 AES 进行对称加密的 C# 代码:

public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] key, byte[] iv)
{using (Aes aesAlg = Aes.Create()){aesAlg.Key = key;aesAlg.IV = iv;ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);using (MemoryStream msEncrypt = new MemoryStream()){using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)){using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)){swEncrypt.Write(plainText);}return msEncrypt.ToArray();}}}
}
  1. 原理注释

这段代码就像是一场精心编排的加密魔术,将明文字符串plainText加密成字节数组返回。具体步骤如下:

  • 首先,通过Aes.Create()创建一个 AES 加密算法的实例aesAlg 。这个实例是我们进行加密操作的核心工具,它提供了一系列的属性和方法来配置和执行加密过程 。

  • 然后,设置aesAlg的Key和IV属性。Key是加密和解密使用的密钥,必须妥善保管,因为一旦密钥泄露,加密的数据就可能被轻易破解 。IV(Initialization Vector,初始化向量)是一个随机值,用于增加加密的安全性,它和密钥一起确保相同的明文在不同的加密操作中生成不同的密文,防止攻击者通过分析密文来破解加密算法 。

  • 接着,调用aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)创建一个加密器encryptor 。这个加密器负责执行实际的加密操作,它根据设置的密钥和初始化向量,将明文数据按照 AES 算法的规则进行加密变换 。

  • 之后,创建一个MemoryStream对象msEncrypt,它用于在内存中存储加密后的字节数据 。同时,创建一个CryptoStream对象csEncrypt,并将其与msEncrypt和encryptor关联起来 。CryptoStream就像是一个桥梁,它将加密器和内存流连接起来,使得加密后的字节数据能够正确地写入到内存流中 。

  • 再创建一个StreamWriter对象swEncrypt,它用于将明文字符串写入到CryptoStream中 。在写入过程中,CryptoStream会自动调用加密器对写入的数据进行加密,并将加密后的字节数据存储到MemoryStream中 。

  • 最后,通过msEncrypt.ToArray()将MemoryStream中的加密字节数据转换为字节数组并返回 。这个字节数组就是加密后的密文,它可以被安全地传输或存储 。

在实际应用中,务必妥善保管好密钥key和初始化向量iv,可以将它们存储在安全的配置文件中,或者使用硬件安全模块(HSM)等设备来存储和管理,以确保加密的安全性 。

(三)非对称加密:RSA 的守护

虽然 AES 对称加密可以高效地保护数据主体,但密钥的传输安全是一个关键问题。为了解决这个问题,我们使用 RSA 非对称加密来保护 AES 密钥的传输。RSA(Rivest-Shamir-Adleman)是一种经典的非对称加密算法,它基于大整数分解的数学难题,提供了极高的安全性 。

  1. 代码实现

以下是用 RSA 加密 AES 密钥的 C# 代码:

public static byte[] EncryptUsingRSA(byte[] dataToEncrypt, RSAParameters publicKey)
{using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()){rsa.ImportParameters(publicKey);return rsa.Encrypt(dataToEncrypt, false); // false 表示使用公钥加密}
}
  1. 原理注释

这段代码的作用是使用 RSA 的公钥对需要加密的数据dataToEncrypt(通常是 AES 密钥)进行加密 。具体实现步骤如下:

  • 首先,创建一个RSACryptoServiceProvider对象rsa,它是 RSA 加密算法在 C# 中的实现类,提供了一系列用于 RSA 加密、解密、签名和验证的方法 。

  • 然后,通过rsa.ImportParameters(publicKey)导入 RSA 的公钥参数publicKey 。公钥参数包含了用于加密的关键信息,通过导入公钥参数,rsa对象就可以使用这个公钥进行加密操作 。

  • 最后,调用rsa.Encrypt(dataToEncrypt, false)方法对数据dataToEncrypt进行加密 。其中,第二个参数false表示使用公钥进行加密 。加密后的字节数组将被返回,这个加密后的字节数组就是经过 RSA 公钥加密后的 AES 密钥,只有拥有对应私钥的接收方才能解密得到原始的 AES 密钥 。

在这个过程中,RSA 就像一位忠诚的骑士,手持公钥之剑,守护着我们的 AES 密钥安全过河(在网络中传输) 。公钥可以公开分发,任何人都可以使用它来加密数据,但只有持有对应私钥的接收方才能解密 。因此,私钥的安全性至关重要,必须严格保密,防止私钥泄露导致加密数据被破解 。

第三步:实战演练 —— 整合加密步骤

(一)生成 RSA 密钥对

在实际应用中,首先需要生成 RSA 密钥对,这是实现非对称加密的基础。在 C# 中,使用RSA.Create()方法可以轻松生成 RSA 密钥对,其中包含公钥和私钥 。公钥用于加密数据,私钥用于解密数据,两者相互关联且缺一不可 。以下是生成 RSA 密钥对的代码示例:

using (RSA rsa = RSA.Create())
{// 导出公钥参数RSAParameters publicKey = rsa.ExportParameters(false);// 导出私钥参数RSAParameters privateKey = rsa.ExportParameters(true);// 这里可以将公钥和私钥保存到安全的地方,例如配置文件或密钥管理系统// 为了演示方便,我们直接打印公钥和私钥的字节数组Console.WriteLine("公钥: " + BitConverter.ToString(publicKey.Exponent).Replace("-", "") + BitConverter.ToString(publicKey.Modulus).Replace("-", ""));Console.WriteLine("私钥: " + BitConverter.ToString(privateKey.D).Replace("-", "") + BitConverter.ToString(privateKey.Modulus).Replace("-", ""));
}

在这段代码中,RSA.Create()创建了一个RSA对象实例,它是 RSA 加密算法的具体实现 。通过rsa.ExportParameters(false)方法导出公钥参数,其中false表示不包含私钥信息 ;通过rsa.ExportParameters(true)方法导出私钥参数,true表示包含私钥信息 。在实际应用中,私钥必须严格保密,建议将其存储在安全的硬件设备(如硬件安全模块 HSM)或经过加密的存储介质中 ,以防止私钥泄露导致加密体系被攻破 。

(二)使用 AES 加密数据

选择一段明文数据,然后利用前面实现的 AES 加密方法对其进行加密 。假设我们有一段表示用户敏感信息的字符串,需要将其加密后传输 。以下是使用 AES 加密数据的示例代码:

// 假设这是我们要加密的明文数据
string plainText = "用户的敏感信息,如身份证号、银行卡号等";
// 生成AES加密所需的密钥和初始化向量
byte[] key = new byte[32]; // 32字节的密钥,适用于AES-256
byte[] iv = new byte[16]; // 16字节的初始化向量
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{rng.GetBytes(key);rng.GetBytes(iv);
}
// 调用AES加密方法
byte[] encryptedBytes = EncryptStringToBytes_Aes(plainText, key, iv);
// 将加密后的字节数组转换为Base64字符串,以便于传输或存储
string encryptedText = Convert.ToBase64String(encryptedBytes);
Console.WriteLine("加密后的密文: " + encryptedText);

在这段代码中,首先定义了要加密的明文字符串plainText 。然后通过RNGCryptoServiceProvider生成随机的 AES 密钥key和初始化向量iv ,确保每次加密使用的密钥和向量都是不同的,增加加密的安全性 。接着调用之前实现的EncryptStringToBytes_Aes方法对明文进行加密,得到加密后的字节数组encryptedBytes 。最后,为了便于传输和存储,将加密后的字节数组转换为 Base64 编码的字符串encryptedText 。

(三)用 RSA 加密 AES 密钥

为了保证 AES 密钥在传输过程中的安全,我们使用 RSA 的公钥对 AES 密钥进行加密 。假设已经生成了 RSA 密钥对,并且获取到了公钥参数 。以下是用 RSA 加密 AES 密钥的代码:

// 假设已经生成了RSA密钥对,并获取到公钥参数
RSAParameters publicKey = GetPublicKey(); // 假设这是获取公钥的方法
// 使用RSA加密AES密钥
byte[] encryptedAesKey = EncryptUsingRSA(key, publicKey);
// 将加密后的AES密钥转换为Base64字符串,以便于传输
string encryptedAesKeyText = Convert.ToBase64String(encryptedAesKey);
Console.WriteLine("加密后的AES密钥: " + encryptedAesKeyText);

在这段代码中,首先通过GetPublicKey()方法获取 RSA 公钥参数(这里假设已经有一个方法来获取公钥) 。然后调用EncryptUsingRSA方法,使用 RSA 公钥对 AES 密钥key进行加密,得到加密后的 AES 密钥字节数组encryptedAesKey 。最后,同样将加密后的 AES 密钥转换为 Base64 编码的字符串encryptedAesKeyText ,方便在网络中传输 。

(四)发送加密后的数据

在完成数据的加密和 AES 密钥的加密后,我们将加密后的数据和加密后的 AES 密钥一起发送给接收方 。接收方在收到数据后,需要按照相反的步骤进行解密 。

  1. 发送方操作

将 AES 加密后的密文encryptedText和 RSA 加密后的 AES 密钥encryptedAesKeyText一起发送给接收方 。可以通过网络请求(如 HTTP 请求)将这些数据发送到目标服务器 。例如,使用HttpClient发送 POST 请求:

using (HttpClient client = new HttpClient())
{var content = new MultipartFormDataContent();content.Add(new StringContent(encryptedText), "encryptedData");content.Add(new StringContent(encryptedAesKeyText), "encryptedAesKey");HttpResponseMessage response = client.PostAsync("https://example.com/api/receive", content).Result;if (response.IsSuccessStatusCode){Console.WriteLine("数据发送成功");}else{Console.WriteLine("数据发送失败: " + response.StatusCode);}
}

在这段代码中,创建了一个HttpClient对象用于发送 HTTP 请求 。使用MultipartFormDataContent将加密后的密文和加密后的 AES 密钥作为表单数据添加到请求中 ,分别命名为encryptedData和encryptedAesKey 。然后通过client.PostAsync方法发送 POST 请求到指定的 API 地址https://example.com/api/receive ,并根据响应状态码判断数据是否发送成功 。

  1. 接收方操作

接收方在收到请求后,首先使用自己的 RSA 私钥解密得到 AES 密钥 ,然后再用 AES 密钥解密密文数据 。以下是接收方的解密代码示例:

// 假设已经获取到RSA私钥参数
RSAParameters privateKey = GetPrivateKey(); // 假设这是获取私钥的方法
// 从请求中获取加密后的AES密钥和密文数据
string receivedEncryptedAesKey = Request.Form["encryptedAesKey"];
string receivedEncryptedText = Request.Form["encryptedData"];
// 将Base64编码的字符串转换回字节数组
byte[] receivedEncryptedAesKeyBytes = Convert.FromBase64String(receivedEncryptedAesKey);
byte[] receivedEncryptedTextBytes = Convert.FromBase64String(receivedEncryptedText);
// 使用RSA私钥解密AES密钥
byte[] decryptedAesKey = DecryptUsingRSA(receivedEncryptedAesKeyBytes, privateKey);
// 使用AES密钥解密密文数据
string decryptedText = DecryptStringFromBytes_Aes(receivedEncryptedTextBytes, decryptedAesKey, GetIV()); // 假设这是获取IV的方法
Console.WriteLine("解密后的明文: " + decryptedText);

在这段代码中,首先通过GetPrivateKey()方法获取 RSA 私钥参数(假设已经有获取私钥的方法) 。然后从 HTTP 请求的表单数据中获取加密后的 AES 密钥receivedEncryptedAesKey和密文数据receivedEncryptedText 。将这两个 Base64 编码的字符串转换回字节数组 。接着调用DecryptUsingRSA方法(假设已经实现该方法用于 RSA 解密),使用 RSA 私钥对加密后的 AES 密钥进行解密,得到原始的 AES 密钥decryptedAesKey 。最后,调用DecryptStringFromBytes_Aes方法(假设已经实现该方法用于 AES 解密),使用解密得到的 AES 密钥和获取到的初始化向量(这里假设通过GetIV()方法获取)解密密文数据,得到原始的明文decryptedText 。通过这样的流程,实现了数据的安全传输和解密 。

相关文章:

3步打造C# API安全密盾

引言:API 安全的重要性 在数字化浪潮中,应用程序编程接口(API)已成为不同软件系统之间通信和数据交互的关键桥梁。无论是企业内部的微服务架构,还是面向外部用户的在线服务,API 都承担着数据传输和业务逻辑…...

项目实操:windows批处理拉取git库和处理目录、文件

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...

接入 deepseek 实现AI智能问诊

1. 准备工作 注册 DeepSeek 账号 前往 DeepSeek 官网 注册账号并获取 API Key。 创建 UniApp 项目 使用 HBuilderX 创建一个新的 UniApp 项目(选择 Vue3 或 Vue2 模板)。 安装依赖 如果需要在 UniApp 中使用 HTTP 请求,推荐使用 uni.requ…...

ubuntu22.04源码编译mysql8.0.X详细流程【由deepseek提供】

以下是在 Ubuntu 22.04 上从源代码编译安装 MySQL 8.0.X(以 MySQL 8.0.37 为例)的详细操作流程: 一、准备工作 1. 更新系统 sudo apt update && sudo apt upgrade -y sudo apt install -y build-essential cmake pkg-config libssl…...

富唯智能复合机器人拓展工业新维度

富唯智能复合机器人是富唯智能倾力打造的一款集高度自动化、智能化和多功能性于一体的机器人。它融合了机械、电子、计算机、传感器等多个领域的前沿技术,通过精密的算法和控制系统,实现了对复杂生产环境的快速适应和高效作业。 富唯智能复合机器人的特点…...

【2】高并发导出场景下,服务器性能瓶颈优化方案-异步导出

Java 异步导出是一种在处理大量数据或复杂任务时优化性能和用户体验的重要技术。 1. 异步导出的优势 异步导出是指将导出操作从主线程中分离出来,通过后台线程或异步任务完成数据处理和文件生成。这种方式可以显著减少用户等待时间,避免系统阻塞&#x…...

verdi 查看覆盖率

点击Tools -> Coverage,会出现一个Verdi:vdCoverage:1页面点击File->Open/Add Database, 会出现一个 Open/Add Coverage Database页面, 在Design Hierarchy/Testbench Location 中输入 vdb路径点击… , 会出现当前路径下的文件&#xf…...

【React】路由处理的常见坑与解决方法,React Router 的动态路由与懒加载问题

在使用 React Router 时,动态路由和懒加载是非常常见的需求,但也可能会遇到一些坑。以下是常见问题以及对应的解决方法。 一、React Router 动态路由常见问题 1. 动态路由匹配问题 动态路由通常通过 :param 定义路径参数,但如果路径参数与静态路由有重叠,可能会导致匹配问…...

OKHttp拦截器解析

OKHttp涉及到拦截器大概的执行步骤为: 1.通过newCall生成RealCall对象 具体代码如下: Override public Call newCall(Request request) {return new RealCall(this, request, false /* for web socket */);}2.调用Call的execute方法 当然这也可以是执…...

顺序表和链表

线性表 线性表(linear list)是n 个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构。 常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物…...

若依框架使用(低级)

克隆源码 浏览器搜索若依,选择 RuoYi-Vue RuoYi-Vue RuoYi-Vue 重要的事情说三遍,进入gitee 下面这个页面(注意红色框起来的部分) 进入Gitee进行下载 我下载的是最新的springboot3 下载好后我们可以选择一个文件夹&#xff0…...

Spring JDBC模块解析 -深入SqlParameterSource

在前面的博客中,我们探讨了Spring Data Access Module中的主要组件: JdbcTemplate和SimpleJdbcInsert。在这两部分的基础上,我们将继续探讨更详细 的用法,包括如何使用RowMapper和SqlParameterSource等高级主题。 JdbcTemplate …...

SQL中Limit的用法详解

SQL中的LIMIT关键字是一个非常有用的工具,它可以用来限制查询结果返回的记录数量。文章将详细解析LIMIT关键字的使用方法,包括它的基本用法,以及在查询数据时如何配合使用LIMIT与OFFSET。我会通过示例代码演示LIMIT在单行结果集和多行结果集情…...

mac 安装 dotnet 环境

目录 一、安装准备 二、安装方法(两种任选) 方法 1:使用官方安装包(推荐新手) 方法 2:使用 Homebrew(适合开发者) 1. 安装 Homebrew(如未安装) 2. 通过 …...

DeepSeek辅助学术写作【句子重写】效果如何?

句子重写(功能指数:★★★★★) 当我们想引用一篇文章中的一-些我们认为写得很好的句子时,如果直接将原文加人自己的文章,那么即使我们标注上了引用,也依旧会被查重软件计算在重复比例中。查重比例过高的话,会影响投稿或毕业答辩送…...

SpringUI Web高端动态交互元件库

Axure Web高端动态交互元件库是一个专为Web设计与开发领域设计的高质量资源集合,旨在加速原型设计和开发流程。以下是关于这个元件库的详细介绍: 一、概述 Axure Web高端动态交互元件库是一个集成了多种预制、高质量交互组件的工具集合。这些组件经过精…...

QT +FFMPEG4.3 拉取 RTMP/http-flv 流播放 AVFrame转Qimage

QT FFMPEG4.3 拉取 RTMP/http-flv 流播放 Cc_Video_thread.h #ifndef CC_VIDEO_THREAD_H #define CC_VIDEO_THREAD_H#include <QThread> #include <QAtomicInt> #include <QImage>#ifdef __cplusplus extern "C" { #endif #include <libavfor…...

Docker最佳实践:安装Nacos

文章目录 Docker最佳实践&#xff1a;安装Nacos一、引言二、安装 Nacos1、拉取 Nacos Docker 镜像2、启动 Nacos 容器 三、配置 Nacos&#xff08;可选&#xff09;四、使用示例1、服务注册2、服务发现 五、总结 Docker最佳实践&#xff1a;安装Nacos 一、引言 Nacos 是阿里巴…...

106,【6】 buuctf web [SUCTF 2019]CheckIn

进入靶场 文件上传 老规矩&#xff0c;桌面有啥传啥 过滤了<? 寻找不含<?的一句话木马 文件名 123(2).php.jpg 文件内容 GIF89a? <script language"php">eval($_GET[123]);</script> 123即密码&#xff0c;可凭借个人喜好更换 再上传一个文…...

【Linux】27.Linux 多线程(1)

文章目录 1. Linux线程概念1.1 线程和进程1.2 虚拟地址是如何转换到物理地址的1.3 线程的优点1.4 线程的缺点1.5 线程异常1.6 线程用途 2. Linux进程VS线程2.1 进程和线程2.2 关于进程线程的问题 3. Linux线程控制3.1 POSIX线程库3.2 创建线程3.3 线程终止3.4 线程等待3.5 分离…...

旋转变压器工作及解调原理

旋转变压器 旋转变压器是一种精密的位置、速度检测装置&#xff0c;广泛应用在伺服控制、机器人、机械工具、汽车、电力等领域。但是&#xff0c;旋转变压器在使用时并不能直接提供角度或位置信息&#xff0c;需要特殊的激励信号和解调、计算措施&#xff0c;才能将旋转变压器…...

字符串转浮点数函数atof、strtod、strtof和strtold使用场景

字符串转浮点数函数 atof、strtod、strtof 和 strtold 在 C 语言标准库中都有各自的使用场景&#xff0c;它们的主要功能是将字符串转换为浮点数&#xff0c;但在处理的浮点数类型、错误处理机制和精度方面有所不同。 一、atof 函数使用场景 atof&#xff08;ASCII to Float&…...

GD32F4xx系列微控制器中,定时器的主模式(Master Mode)和从模式(Slave Mode)

在GD32F4xx系列微控制器中&#xff0c;定时器的主模式&#xff08;Master Mode&#xff09;和从模式&#xff08;Slave Mode&#xff09;是两种不同的工作模式&#xff0c;它们的主要区别在于定时器的操作是否依赖于外部信号或另一个定时器的输出信号。以下是对这两种模式的详细…...

深度学习系列--03.激活函数

一.定义 激活函数是一种添加到人工神经网络中的函数&#xff0c;它为神经网络中神经元的输出添加了非线性特性 在神经网络中&#xff0c;神经元接收来自其他神经元的输入&#xff0c;并通过加权求和等方式计算出一个净输入值。激活函数则根据这个净输入值来决定神经元是否应该…...

在linux 中搭建deepseek 做微调,硬件配置要求说明

搭建 可参考 使用deepseek-CSDN博客 官方网站&#xff1a;DeepSeek DeepSeek 是一个基于深度学习的开源项目&#xff0c;旨在通过深度学习技术来提升搜索引擎的准确性和效率。如果你想在 Linux 系统上搭建 DeepSeek&#xff0c;你可以遵循以下步骤。这里我将提供一个基本的指…...

机器学习之数学基础:线性代数、微积分、概率论 | PyTorch 深度学习实战

前一篇文章&#xff0c;使用线性回归模型逼近目标模型 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于 强化学习必修课&#xff1a;引领人工智能新时代【梗直哥瞿炜】 线性代数、微积分、概率论 …...

MySQL - Navicat自动备份MySQL数据

对于从事IT开发的工程师&#xff0c;数据备份我想大家并不陌生&#xff0c;这件工程太重要了&#xff01;对于比较重要的数据&#xff0c;我们希望能定期备份&#xff0c;每天备份1次或多次&#xff0c;或者是每周备份1次或多次。 如果大家在平时使用Navicat操作数据库&#x…...

javaEE-9.HTML入门

目录 一.什么是html 二.认识html标签 1.标签的特点: 2.html文件基本结构 3.标签的层次结构 三、html工具 四、创建第一个文件 五.html常见标签 1标题标签h1-h6 2.段落标签:p 3.换行标签:br 4.图片标签:img 图片路径有1三种表示形式: 5.超链接:a 链接的几种形式: …...

springcloud微服务使用不同端口启动同一服务

若想同时启动两个服务&#xff0c;则会产生端口冲突&#xff0c;在启动类设置界面&#xff0c;添加虚拟机选项&#xff0c;随后设置 -Dserver.portxxxx即可...

JavaScript系列(61)--边缘计算应用开发详解

JavaScript边缘计算应用开发详解 &#x1f310; 今天&#xff0c;让我们深入探讨JavaScript的边缘计算应用开发。边缘计算是一种将计算和数据存储分布到更靠近数据源的位置的架构模式&#xff0c;它能够提供更低的延迟和更好的实时性能。 边缘计算基础架构 &#x1f31f; &am…...

【容器技术01】使用 busybox 构建 Mini Linux FS

使用 busybox 构建 Mini Linux FS 构建目标 在 Linux 文件系统下构建一个 Mini 的文件系统&#xff0c;构建目标如下&#xff1a; minilinux ├── bin │ ├── ls │ ├── top │ ├── ps │ ├── sh │ └── … ├── dev ├── etc │ ├── g…...

Effective Python系列(1.3):使用zip函数同时遍历两个迭代器

zip函数是 Python 中的一个内置函数&#xff0c;用于将多个可迭代对象&#xff08;如列表、元组等&#xff09;的元素配对&#xff0c;生成一个迭代器。 使用 zip 函数的好处之一就是能够节省内存空间&#xff0c;因为该函数会创建惰性生成器&#xff0c;每次遍历时只生成一个元…...

gitlab个别服务无法启动可能原因

目录 一、gitlab的puma服务一直重启 1. 查看日志 2. 检查配置文件 3. 重新配置和重启 GitLab 4. 检查系统资源 5. 检查依赖和服务状态 6. 清理和优化 7. 升级 GitLab 8. 查看社区和文档 二、 gitlab个别服务无法启动可能原因 1.服务器内存或磁盘已满 2.puma端口冲突…...

基于Springboot+vue的租车网站系统

基于SpringbootVue的租车网站系统是一个现代化的在线租车平台&#xff0c;它结合了Springboot的后端开发能力和Vue的前端交互优势&#xff0c;为用户和汽车租赁公司提供了一个高效、便捷、易用的租车体验和管理工具。以下是对该系统的详细介绍&#xff1a; 一、系统架构 后…...

Github - 记录一次对“不小心包含了密码的PR”的修复

Github - 记录一次对“不小心包含了密码的PR”的修复 前言 和好朋友一起开发一个字节跳动青训营抖音电商后端(now private)的项目&#xff0c;某大佬不小心把本地一密码commit上去并提了PR。 PR一旦发出则无法被删除&#xff0c;且其包含的commit也能被所有能看到这个仓库的…...

【后端开发】系统设计101——通信协议,数据库与缓存,架构模式,微服务架构,支付系统(36张图详解)

【后端开发】系统设计101——通信协议&#xff0c;数据库与缓存&#xff0c;架构模式&#xff0c;微服务架构&#xff0c;支付系统&#xff08;36张图&#xff09; 文章目录 1、通信协议通信协议REST API 对比 GraphQL&#xff08;前端-web服务&#xff09;grpc如何工作&#x…...

SpringMVC请求

一、RequestMapping注解 RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系 RequestMapping注解可以作用在方法和类上 1. 作用在类上&#xff1a;第一级的访问目录 2. 作用在方法上&#xff1a;第二级的访问目录 3. 细节&#xff1a;路径可以不编写 / 表示应…...

【学术征稿-组织单位 武汉理工大学西安理工大学、西安财经大学】第三届通信网络与机器学习(CNML 2025)

重要信息 官网&#xff1a;www.iccnml.org 大会时间&#xff1a;2025年2月21日-23日 大会地点&#xff1a;中国 南京 通信网络 通信是人与人之间通过某种媒体进行的信息交流与传递。网络是用物理链路将各个孤立的工作站或主机相连在一起&#xff0c;组成的数据链路。通信网…...

代码随想录算法训练营打卡第55天:并查集相关问题;

Java并查集的模板 //并查集模板 class DisJoint{private int[] father;public DisJoint(int N) {father new int[N];for (int i 0; i < N; i){father[i] i;}}public int find(int n) {return n father[n] ? n : (father[n] find(father[n]));}public void join (int …...

设计模式学习

1.设计模式分类 1.创建型模式 用于描述“怎样创建对象”&#xff0c;主要特点是“将对象的创建与使用分离”。 单例&#xff0c;原型&#xff0c;工厂方法&#xff0c;抽象工厂&#xff0c;建造者 2.结构型模式 用于描述如何将类或对象按某种布局组成更大的结构 代理&…...

js-对象-JSON

JavaScript自定义对象 JSON 概念: JavaScript Object Notation&#xff0c;JavaScript对象标记法. JSON 是通过JavaScript 对象标记法书写的文本。 由于其语法简单&#xff0c;层次结构鲜明&#xff0c;现多用于作为数据载体&#xff0c;在网络中进行数据传输. json中属性名(k…...

C/C++编译器

C/C 代码是不可跨平台的&#xff0c;Windows 和 Unix-like 有着不同的 API&#xff0c;C/C 在不同平台有着不同编译器。 MSVC Windows 平台&#xff0c;MSVC 是 Visual Studio 中自带的 C/C 编译器。 GCC Unix-like 平台&#xff0c;GCC 原名 GNU C Compiler&#xff0c;后…...

【R语言】数据操作

一、查看和编辑数据 1、查看数据 直接打印到控制台 x <- data.frame(a1:20, b21:30) x View()函数 此函数可以将数据以电子表格的形式进行展示。 用reshape2包中的tips进行举例&#xff1a; library("reshape2") View(tips) head()函数 查看前几行数据&…...

Linux 安装 RabbitMQ

Linux下安装RabbitMQ 1 、获取安装包 # 地址 https://github.com/rabbitmq/erlang-rpm/releases/download/v21.3.8.9/erlang-21.3.8.9-1.el7.x86_64.rpm erlang-21.3.8.9-1.el7.x86_64.rpmsocat-1.7.3.2-1.el6.lux.x86_64.rpm# 地址 https://github.com/rabbitmq/rabbitmq-se…...

“AI智能分析综合管理系统:企业管理的智慧中枢

在如今这个快节奏的商业世界里&#xff0c;企业面临的挑战越来越多&#xff0c;数据像潮水一样涌来&#xff0c;管理工作变得愈发复杂。为了应对这些难题&#xff0c;AI智能分析综合管理系统闪亮登场&#xff0c;它就像是企业的智慧中枢&#xff0c;让管理变得轻松又高效。 过去…...

2024最新版Java面试题及答案,【来自于各大厂】

发现网上很多Java面试题都没有答案&#xff0c;所以花了很长时间搜集整理出来了这套Java面试题大全~ 篇幅限制就只能给大家展示小册部分内容了&#xff0c;需要完整版的及Java面试宝典小伙伴点赞转发&#xff0c;关注我后在【翻到最下方&#xff0c;文尾点击名片】即可免费获取…...

调用腾讯云批量文本翻译API翻译srt字幕

上一篇文章介绍了调用百度翻译API翻译日文srt字幕的方法。百度翻译API是get方式调用&#xff0c;参数都放在ur中&#xff0c;每次调用翻译文本长度除了接口限制外&#xff0c;还有url长度限制&#xff0c;而日文字符通过ur转码后会占9个字符长度&#xff0c;其实从这个角度来讲…...

【分块解决大文件上传的最佳实践】

前言 前几天看了一篇关于大文件上传分块实现的博客&#xff0c;代码实现过于复杂且冗长&#xff0c;而且没有进行外网上传的测试。因此&#xff0c;我决定自己动手实现一个大文件上传&#xff0c;并进行优化。 实现思路 在许多应用中&#xff0c;大文件上传是常见的需求&…...

机器学习中的关键概念:通过SKlearn的MNIST实验深入理解

欢迎来到我的主页&#xff1a;【Echo-Nie】 本篇文章收录于专栏【机器学习】 1 sklearn相关介绍 Scikit-learn 是一个广泛使用的开源机器学习库&#xff0c;提供了简单而高效的数据挖掘和数据分析工具。它建立在 NumPy、SciPy 和 matplotlib 等科学计算库之上&#xff0c;支持…...

【Elasticsearch】post_filter

post_filter是 Elasticsearch 中的一种后置过滤机制&#xff0c;用于在查询执行完成后对结果进行过滤。以下是关于post_filter的详细介绍&#xff1a; 工作原理 • 查询后过滤&#xff1a;post_filter在查询执行完毕后对返回的文档集进行过滤。这意味着所有与查询匹配的文档都…...