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

python实现RSA算法

目录

  • 一、算法简介
  • 二、算法描述
    • 2.1 密钥产生
    • 2.2 加密过程
    • 2.3 解密过程
    • 2.4 证明解密正确性
  • 三、相关算法
    • 3.1 欧几里得算法
    • 3.2 扩展欧几里得算法
    • 3.3 模重复平方算法
    • 3.4 Miller-Rabin 素性检测算法
  • 四、算法实现
  • 五、演示效果

一、算法简介

RSA算法是一种非对称加密算法,它基于一个简单的数论事实:将两个大质数相乘是容易的,但反过来,对它们的乘积进行因数分解却极其困难。RSA算法由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)在1977年共同发明,因此以他们姓氏的首字母命名。

RSA算法的特点总结,以下是一些关键点:

  1. 非对称加密

    • RSA是一种非对称加密算法,使用一对密钥:公钥用于加密,私钥用于解密。这种设计使得RSA非常适合于安全通信,因为公钥可以公开分享,而私钥必须保密。
  2. 安全性

    • RSA的安全性基于大整数分解的困难性。只要密钥长度足够长,目前没有已知的算法能在合理时间内破解RSA加密。
  3. 数字签名

    • RSA算法不仅可以用于加密,还可以用于数字签名。发送者可以用自己的私钥对消息进行签名,接收者可以用发送者的公钥验证签名,确保消息的完整性和来源。
  4. 密钥长度

    • RSA需要较长的密钥长度来保证安全性。随着计算能力的提升,推荐的密钥长度也在不断增加,目前推荐至少使用2048位的密钥长度。
  5. 计算效率

    • 相比于对称加密算法,RSA在加密和解密时的计算效率较低,特别是对于大量数据的处理。因此,RSA通常不用于大量数据的直接加密,而是用于加密对称密钥或进行数字签名。
  6. 广泛的应用

    • RSA算法被广泛应用于互联网安全通信,如SSL/TLS协议中,用于安全地传输敏感信息,如信用卡信息、个人身份信息等。
  7. 标准化

    • RSA算法已经被多个国际标准组织采纳为标准,如ISO/IEC和ITU-T。
  8. 密钥管理

    • 由于RSA使用非对称密钥,密钥管理相对复杂,需要确保私钥的安全存储和传输。
  9. 抗量子计算

    • 随着量子计算的发展,RSA算法可能面临安全威胁。量子计算机理论上能够快速分解大整数,从而破解RSA加密。因此,后量子密码学正在研究能够抵抗量子攻击的加密算法。
  10. 灵活性

    • RSA算法允许用户根据需要选择不同的参数,如密钥长度和加密指数,以满足不同的安全和性能需求。

RSA算法的这些特点使其成为现代密码学中一个非常重要的工具,尽管它也有一些局限性,如计算效率和密钥管理的复杂性。

二、算法描述

2.1 密钥产生

(1)选取两个保密大素数 p p p q q q
(2)计算模数 n = p ∗ q n=p*q n=pq n n n的欧拉函数值 φ ( n ) = ( p − 1 ) ( q − 1 ) φ(n)=(p-1)(q-1) φ(n)=(p1)(q1)
(3)在 ( 1 , φ ( n ) ) (1,φ(n)) (1,φ(n))之间任选一整数 e e e,使其满足 g c d ( e , φ ( n ) ) = 1 gcd(e,φ(n))=1 gcd(e,φ(n))=1,即 e e e φ ( n ) φ(n) φ(n)互素
(4)计算 e e e在模 φ ( n ) φ(n) φ(n)下的乘法逆元 d d d,即 e ∗ d ≡ 1 ( m o d φ ( n ) ) e*d\equiv 1\pmod{φ(n)} ed1(modφ(n)),因为 e e e φ ( n ) φ(n) φ(n)互素,由裴蜀定理可知整数 d d d一定且唯一存在
(5) { e , n } \{e,n\} {e,n}作为公钥, { d , n } \{d,n\} {d,n}作为私钥

2.2 加密过程

为了保证加解密的正确性,首先将明文 m m m进行分组,每个分组对应的十进制数值应小于模数 n n n,即分组长度小于 log ⁡ 2 n \log_2 n log2n,然后进行分组加密。 加密运算: m e m o d n = c 加密运算:m^{e}\mod{n}=c 加密运算:memodn=c

2.3 解密过程

对密文 c c c进行分组解密 解密运算: c d m o d n = m 解密运算:c^{d}\mod{n}=m 解密运算:cdmodn=m

2.4 证明解密正确性

由加密过程 m e m o d n = c m^{e}\mod{n}=c memodn=c和解密过程 c d m o d n = m c^{d}\mod{n}=m cdmodn=m,可知 c d m o d n = m e d m o d n c^{d}\mod{n}=m^{ed}\mod{n} cdmodn=medmodn
又因为 e ∗ d ≡ 1 ( m o d φ ( n ) ) e*d\equiv 1\pmod{φ(n)} ed1(modφ(n)),可得 e ∗ d = k φ ( n ) + 1 e*d=kφ(n)+1 ed=kφ(n)+1 k ∈ Z k\in\mathbb{Z} kZ,所以 c d m o d n = m e d m o d n = m k φ ( n ) + 1 m o d n c^{d}\mod{n}=m^{ed}\mod{n}= m^{kφ(n)+1}\mod{n} cdmodn=medmodn=mkφ(n)+1modn
所以要证 c d m o d n = m c^{d}\mod{n}=m cdmodn=m成立,即证 m k φ ( n ) + 1 m o d n = m m^{kφ(n)+1}\mod{n}=m mkφ(n)+1modn=m成立,注意: m < n m<n m<n
分两种情况讨论:


(1) m m m n n n互素
由欧拉定理可得, m φ ( n ) ≡ 1 ( m o d n ) m^{φ(n)}\equiv 1\pmod{n} mφ(n)1(modn),则有 m k φ ( n ) m o d n = 1 k m o d n = 1 m o d n m^{kφ(n)}\mod{n}=1^k\mod{n}=1\mod{n} mkφ(n)modn=1kmodn=1modn,所以 m k φ ( n ) + 1 ≡ m ( m o d n ) m^{kφ(n)+1}\equiv m\pmod{n} mkφ(n)+1m(modn),即证 m k φ ( n ) + 1 m o d n = m m^{kφ(n)+1}\mod{n}=m mkφ(n)+1modn=m成立


(2) m m m n n n不互素
因为 m < n m<n m<n,所以 m m m一定为 p p p q q q的倍数,(如果 m m m同时是 p p p q q q的倍数,则 m m m一定是 p ∗ q p*q pq的倍数,与条件 m < n = p ∗ q m<n=p*q m<n=pq矛盾)。假设 m = t ∗ p m=t*p m=tp t ∈ Z + t\in\mathbb{Z}^+ tZ+,则有 g c d ( m , q ) = 1 gcd(m,q)=1 gcd(m,q)=1,由欧拉定理可得, m φ ( q ) ≡ 1 ( m o d q ) m^{φ(q)}\equiv 1\pmod{q} mφ(q)1(modq),则有 m k φ ( q ) ≡ 1 ( m o d q ) m^{kφ(q)}\equiv 1\pmod{q} mkφ(q)1(modq) m k φ ( q ) ∗ φ ( p ) = m k φ ( n ) ≡ 1 ( m o d q ) m^{kφ(q)*φ(p)}=m^{kφ(n)}\equiv 1\pmod{q} mkφ(q)φ(p)=mkφ(n)1(modq)
所以存在 r ∈ Z r\in\mathbb{Z} rZ,使得 m k φ ( n ) = r ∗ q + 1 m^{kφ(n)}=r*q+1 mkφ(n)=rq+1,等式两边同乘 m m m,可得 m k φ ( n ) + 1 = m ∗ r ∗ q + m = ( t ∗ p ) ∗ r ∗ q + m = t ∗ r ∗ n + m m^{kφ(n)+1}=m*r*q+m=(t*p)*r*q+m=t*r*n+m mkφ(n)+1=mrq+m=(tp)rq+m=trn+m
由上述等式,可得 m k φ ( n ) + 1 ≡ m ( m o d n ) m^{kφ(n)+1}\equiv m\pmod{n} mkφ(n)+1m(modn),即证 m k φ ( n ) + 1 m o d n = m m^{kφ(n)+1}\mod{n}=m mkφ(n)+1modn=m成立
证毕!


三、相关算法

3.1 欧几里得算法

欧几里得算法,又称辗转相除法,是一种用于计算两个非负整数最大公约数(GCD)的古老算法。该算法最早由古希腊数学家欧几里得在其著作《几何原本》中描述,因此得名。

欧几里得算法的基本原理是通过不断用较大的数除以较小的数,并取余数,然后用较小的数和余数继续进行同样的操作,直到余数为0为止。此时,最后的非零余数即为这两个数的最大公约数。

其计算公式可以表示为 g c d ( a , b ) = g c d ( b , a m o d b ) gcd(a,b)=gcd(b,a\mod{b}) gcd(a,b)=gcd(b,amodb),其中 a a a b b b是两个非负整数。
在这里插入图片描述
算法的正确性可以通过数学证明来验证。

例如,假设 x x x a a a b b b的最大公约数,则 x x x能够整除 a a a b b b,表示为 a = k 1 x , k 1 ∈ Z a=k_{1}x,k_{1}\in\mathbb{Z} a=k1x,k1Z b = k 2 x , k 2 ∈ Z b=k_{2}x,k_{2}\in\mathbb{Z} b=k2x,k2Z
由于 a m o d b a\mod{b} amodb的结果是 a a a除以 b b b的余数,根据 a a a b b b的表达式,有 a m o d b = ( k 1 x ) m o d ( k 2 x ) = x ( k 1 m o d k 2 ) a\mod{b}=(k_{1}x)\mod{(k_{2}x)}=x(k_{1}\mod{k_{2}}) amodb=(k1x)mod(k2x)=x(k1modk2),设 m = k 1 m o d k 2 m=k_{1}\mod{k_{2}} m=k1modk2,则有 a m o d b = x m a\mod{b}=xm amodb=xm,所以 x x x也能够整除a a m o d b a\mod{b} amodb,因此 x x x也是 b b b a m o d b a\mod{b} amodb的最大公约数,这说明 g c d ( a , b ) = g c d ( b , a m o d b ) gcd(a, b) = gcd(b, a mod b) gcd(a,b)=gcd(b,amodb)成立。

代码实现:递归方式

def gcd(a: int, b: int) -> int:"""欧几里得算法-求两个数的最大公约数(递归版本):param a: 整数:param b: 整数:return: 返回a、b的最大公约数"""if b == 0:return aelse:return gcd(b, a % b)

代码实现:非递归方式

def gcd(a: int, b: int) -> int:"""欧几里得算法-求两个数的最大公约数(非递归版本):param a: 整数:param b: 整数:return: 返回a、b的最大公约数"""while b != 0:a, b = b, a % breturn a

3.2 扩展欧几里得算法

扩展欧几里得算法(Extended Euclidean Algorithm)是欧几里得算法(也称为辗转相除法)的扩展,用于计算两个整数的最大公约数(GCD)以及找到满足裴蜀等式的整数解。具体来说,对于任意两个整数 a a a b b b,该算法不仅能计算出它们的最大公约数 d d d,还能找到整数 x x x y y y,使得 a x + b y = d ax+by=d ax+by=d成立。

扩展欧几里得算法基于裴蜀定理:对于任意两个不全为0的整数 a a a b b b,必存在整数 x x x y y y,使得 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)成立,其中 g c d ( a , b ) gcd(a,b) gcd(a,b)表示 a a a b b b的最大公约数。

推论: 如果 a a a b b b是不全为0的整数且 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1,则当且仅当存在整数 x x x y y y,使 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)成立

算法通过递归的方式,使用辗转相除法逐步缩小问题规模,直到找到最大公约数,并同时计算出对应的 x x x y y y

应用场景

  1. 求解线性不定方程:扩展欧几里得算法可以用来求解形如 a x + b y = c ax+by=c ax+by=c的线性不定方程,其中 a a a b b b c c c是已知整数, x x x y y y是未知整数。
  2. 求模逆元:在模运算中,扩展欧几里得算法可以用来求解乘法逆元,即找到一个整数 x x x使 a x ≡ 1 ( m o d n ) ax\equiv 1\pmod{n} ax1(modn),其中 n n n是模数。
  3. 求解线性同余方程:扩展欧几里得算法还可以用于求解线性同余方程,即形如 a x ≡ b ( m o d n ) ax\equiv b\pmod{n} axb(modn)的方程。

代码实现:递归方式

def ext_gcd(a: int, b: int) -> tuple:"""扩展欧几里得算法-求乘法逆元(递归版本):param a: 整数:param b: 整数:return: (gcd, x, y),其中gcd是a和b的最大公约数,x和y是整数,满足 a*x + b*y = gcd"""if b == 0:return (a, 1, 0)else:gcd, x1, y1 = ext_gcd(b, a % b)x = y1y = x1 - (a // b) * y1return (gcd, x, y)

代码实现:非递归方式

def ext_gcd(a: int, b: int) -> tuple:"""扩展欧几里得算法-求乘法逆元(非递归版本):param a: 整数:param b: 整数:return: (gcd, x, y),其中gcd是a和b的最大公约数,x和y是整数,满足 a*x + b*y = gcd"""x0, x1, y0, y1 = 1, 0, 0, 1while b != 0:q, a, b = a // b, b, a % bx0, x1 = x1, x0 - q * x1y0, y1 = y1, y0 - q * y1gcd, x, y = a, x0, y0return gcd, x, y

3.3 模重复平方算法

模重复平方算法(Modular Exponentiation by Repeated Squaring)是一种用于高效计算模幂的算法,特别适用于处理大整数幂运算。该算法的核心思想是通过将指数二进制分解,然后利用平方和乘法来计算幂的值。

该算法的优势在于其时间复杂度为 O ( log ⁡ b ) O(\log{b}) O(logb) ,显著提高了大整数幂运算的效率。因此,它在密码学中有着广泛的应用,尤其是在RSA加密算法中,用于快速计算大整数的模幂。

具体来说,模重复平方算法的基本步骤如下:计算 a b m o d n a^{b}\mod{n} abmodn

  1. 指数二进制分解:首先将指数 b b b转换成二进制表示。例如,如果 b = 560 b=560 b=560,其二进制表示为 1000110000 1000110000 1000110000
  2. 初始化结果:初始化结果变量 d d d为1,底数变量 a a a为给定的底数
  3. 循环计算:从高位到低位遍历指数的二进制表示。首先对当前结果变量 d d d进行平方运算对模数 n n n取余;如果 b i = 1 b_{i}=1 bi=1,则再将当前结果变量 d d d乘以底数a 并对模数 n n n取余;
  4. 最终结果:当所有位都处理完毕后,得到的结果即为 a b m o d n a^{b}\mod{n} abmodn

例如: 7 560 m o d 561 7^{560}\mod{561} 7560mod561

i i i9876543210
b i b_{i} bi1000110000
c c c01248173570140280560
d d d1749157526160241298166671

代码实现:

def quick_mod(a: int, b: int, mod: int) -> int:"""模重复平方算法-大数的模幂运算:param a: 底数:param b: 指数:param mod: 模数:return: 返回余数d"""c, d = 0, 1# 将 b 转为二进制字符串bin_b = bin(b)[2:]for i in bin_b:c = c * 2d = d * d % modif i == '1':c = c + 1d = (d * a) % modreturn d

3.4 Miller-Rabin 素性检测算法

Miller-Rabin素性检测算法是一种用于判断一个数是否为素数的概率性算法。该算法基于费马小定理的逆定理,并通过随机化方法来提高素性检测的准确性。Miler-Rabin算法的核心思想是利用费马小定理及其扩展形式。

算法检测过程
给定奇数 n ≥ 3 n\geq{3} n3和安全参数/检测次数 k k k,记 n − 1 = 2 s d n-1=2^{s}d n1=2sd d d d为奇数

  1. 随机选取整数 a a a 2 ≤ a ≤ n − 2 2\leq{a}\leq{n-2} 2an2,计算 x 0 ≡ a d ( m o d n ) x_{0}\equiv a^{d}\pmod{n} x0ad(modn)
  2. 如果 x 0 = 1 x_{0}=1 x0=1 x 0 = n − 1 x_{0}=n-1 x0=n1,则通过检验, n n n可能为素数,回到 1 1 1;否则,计算 x 1 ≡ x 0 2 ( m o d n ) x_{1}\equiv x_{0}^{2}\pmod{n} x1x02(modn)
  3. 如果 x 1 = n − 1 x_{1}=n-1 x1=n1,则通过检验,可能为素数,回到1;否则,计算 x 2 ≡ x 1 2 ( m o d n ) x_{2}\equiv x_{1}^{2}\pmod{n} x2x12(modn)
  4. 如此继续计算 x i x_{i} xi下去,直到计算到 x s − 1 x_{s-1} xs1;如果 x s − 1 = n − 1 x_{s-1}=n-1 xs1=n1,则通过检验,可能为素数,回到1;否则, n n n为合数
  5. 上述过程重复 k k k

代码实现:

def miller_rabin(n: int, k: int = 100) -> bool:"""使用 Miller-Rabin 算法判断一个整数是否为素数:param n: 待检测的整数:param k: 迭代次数,k 越大,准确率越高:return: 如果 n 是素数,返回 True;否则返回 False"""# 特殊情况处理if n <= 1:return Falseif n <= 3:return Trueif n % 2 == 0:return False# 将 n-1 写成 2^r * d 的形式r, d = 0, n - 1while d % 2 == 0:r += 1d //= 2# 进行 k 次迭代for _ in range(k):a = random.randint(2, n - 2)x = pow(a, d, n)if x == 1 or x == n - 1:continuefor _ in range(r - 1):x = pow(x, 2, n)if x == n - 1:breakelse:return Falsereturn True

四、算法实现

import randomdef int2bytes(integer: int) -> bytes:"""整数转换成字节串:param integer::return: 返回字节串"""# 1.计算所需的最小字节数if integer == 0:len = 1else:len = int((integer.bit_length() + 7) // 8)# 2.整数转换为字节串byte_string = integer.to_bytes(len, byteorder='big')return byte_stringdef calculate_block_size(n: int) -> int:"""计算块大小:param n: 模数n:return: 返回块大小,单位:字节/块"""return (n.bit_length() - 1) // 8def gcd(a: int, b: int) -> int:"""欧几里得算法-求两个数的最大公约数:param a: 整数:param b: 整数:return: 返回a、b的最大公约数"""while b != 0:a, b = b, a % breturn adef ext_gcd(a: int, b: int) -> tuple:"""扩展欧几里得算法-求乘法逆元:param a: 整数:param b: 整数:return: (gcd, x, y),其中gcd是a和b的最大公约数,x和y是整数,满足 a*x + b*y = gcd"""x0, x1, y0, y1 = 1, 0, 0, 1while b != 0:q, a, b = a // b, b, a % bx0, x1 = x1, x0 - q * x1y0, y1 = y1, y0 - q * y1gcd, x, y = a, x0, y0return gcd, x, ydef miller_rabin(n: int, k: int = 100) -> bool:"""使用 Miller-Rabin 算法判断一个整数是否为素数:param n: 待检测的整数:param k: 迭代次数,k 越大,准确率越高:return: 如果 n 是素数,返回 True;否则返回 False"""# 特殊情况处理if n <= 1:return Falseif n <= 3:return Trueif n % 2 == 0:return False# 将 n-1 写成 2^r * d 的形式r, d = 0, n - 1while d % 2 == 0:r += 1d //= 2# 进行 k 次迭代for _ in range(k):a = random.randint(2, n - 2)x = pow(a, d, n)if x == 1 or x == n - 1:continuefor _ in range(r - 1):x = pow(x, 2, n)if x == n - 1:breakelse:return Falsereturn Truedef gen_prime(bits: int) -> int:"""随机生成指定位数的素数:param bits: 指定随机生成素数的位数:return: 返回指定位数的随机生成素数"""while True:# 1.生成一个随机的bits的位奇数candidate = random.getrandbits(bits)candidate |= (1 << (bits - 1)) | 1  # 确保最高位和最低位为1# 2.使用Miller-Rabin素性检测算法判断是否为素数if miller_rabin(candidate):return candidatedef quick_mod(a: int, b: int, mod: int) -> int:"""模重复平方算法-大数的模幂运算:param a: 底数:param b: 指数:param mod: 模数:return: 返回余数d"""c, d = 0, 1# 将 b 转为二进制字符串bin_b = bin(b)[2:]for i in bin_b:c = c * 2d = d * d % modif i == '1':c = c + 1d = (d * a) % modreturn ddef gen_key(bits: int = 1024) -> tuple:"""生成密钥对:param bits: 指定生成p,q两个质因数的位数:return: (e,n),(d,n)"""# 1.生成p和q两个质因数p = gen_prime(bits)while True:q = gen_prime(bits)if p != q:break# 2.计算除数n和n的欧拉函数值phin = p * qphi = (p - 1) * (q - 1)# 3.生成与phi互质的公钥e# e=65537while True:e = random.randint(2, phi - 1)# 判断是e、phi否互质if gcd(e, phi) == 1:break# 4.计算私钥d# 确保d是正数并且在 phi 的范围内d = ext_gcd(e, phi)[1] % phireturn (e, n), (d, n)def rsa_encrypt(m: bytes, public_key: int, n: int) -> tuple:"""RSA加密函数:param m: 明文:param public_key: 公钥:param n: 模数:return: 返回加密明文"""# 1.计算块的大小# 保证每明文块的十进制数小于n,单位:字节/块block_size = calculate_block_size(n)# 2.进行加密bytes_encrypted_blocks = []int_encrypted_blocks = []for i in range(0, len(m), block_size):# 取出单个明文快block = m[i:i + block_size]# 将明文块转换为整数int_block = int.from_bytes(block, byteorder='big')# 对明文快进行加密int_encrypted_block = quick_mod(int_block, public_key, n)int_encrypted_blocks.append(int_encrypted_block)# 整数转成字节串bytes_encrypted_block = int2bytes(int_encrypted_block)bytes_encrypted_blocks.append(bytes_encrypted_block)return bytes_encrypted_blocks, int_encrypted_blocks  # 字节串列表/整数列表def rsa_decrypt(c: list, private_key: int, n: int) -> tuple:"""RSA解密函数:param c: 密文:param public_key: 私钥:param n: 模数:return: 返回解密密文"""# 1.计算块的大小block_size = calculate_block_size(n)# 2.进行解密bytes_decrypted_blocks = []int_decrypted_blocks = []for block in c:# 将密文块转换为整数int_block = int.from_bytes(block, byteorder='big')# 对密文块进行解密int_decrypted_block = quick_mod(int_block, private_key, n)int_decrypted_blocks.append(int_decrypted_block)# 整数转成字节串bytes_decrypted_block = int2bytes(int_decrypted_block)bytes_decrypted_blocks.append(bytes_decrypted_block)return bytes_decrypted_blocks, int_decrypted_blocks  # 字节串列表/整数列表if __name__ == '__main__':# 1.生成密钥对public_key, private_key = gen_key()print(f'公钥e:{public_key[0]}')print(f'私钥d:{private_key[0]}')print(f'模数n:{private_key[1]}')# 2.加密m = '你好,世界!Hello world!'m_ = m.encode()print(f'待加密明文:{m}')print(f'待加密明文-字节:{m_}')print(f'待加密明文-数字:{int.from_bytes(m_, byteorder='big')}')c = rsa_encrypt(m_, public_key[0], public_key[1])print(f'加密明文-字节:{b''.join(c[0])}')print(f'加密明文-数字:{c[1]}')# 3.解密m = rsa_decrypt(c[0], private_key[0], private_key[1])print(f'解密密文:{b''.join(m[0]).decode()}')print(f'解密密文-字节:{b''.join(m[0])}')print(f'解密密文-数字:{m[1]}')

五、演示效果

在这里插入图片描述

相关文章:

python实现RSA算法

目录 一、算法简介二、算法描述2.1 密钥产生2.2 加密过程2.3 解密过程2.4 证明解密正确性 三、相关算法3.1 欧几里得算法3.2 扩展欧几里得算法3.3 模重复平方算法3.4 Miller-Rabin 素性检测算法 四、算法实现五、演示效果 一、算法简介 RSA算法是一种非对称加密算法&#xff0c…...

可灵开源视频生成数据集 学习笔记

目录 介绍 可灵团队提出了四个模块的改进&#xff1a; video caption 新指标 vtss 动态质量 静态质量 视频自然性 介绍 在视频数据处理中&#xff0c;建立准确且细致的条件是关键&#xff0c;可灵团队认为&#xff0c;解决这一问题需要关注三个主要方面&#xff1a; 文本…...

告别软文营销瓶颈!5招助你突破限制,实现宣传效果最大化

在当今信息爆炸的时代&#xff0c;软文营销作为品牌推广的重要手段之一&#xff0c;面临着日益激烈的竞争和受众日益提高的辨别力。传统的软文营销方式往往难以穿透消费者的心理防线&#xff0c;实现有效的信息传递和品牌塑造。为了突破这一瓶颈&#xff0c;实现宣传效果的最大…...

秋冬进补防肥胖:辨证施补,健康过冬不增脂

中医理论中的秋冬“封藏” 在中医理论中&#xff0c;认为秋冬季节是人体“封藏”的时期&#xff0c;而“封藏”指的是秋冬季节人体应当减少消耗&#xff0c;蓄积能源&#xff0c;此时进补可以使营养物质易于吸收并蓄积于体内&#xff0c;从而增强体质和抵抗力&#xff0c;为来…...

uniapp radio单选

<uni-data-checkbox v-model"selectedValue" :localdata"quTypeList" change"radioChange"/> //产品类型列表 const quTypeList [{ text: 漆面膜, value: 100, }, { text: 改色…...

通熟易懂地讲解GCC和Makefile

1. 嵌入式开发工具链&#xff1a;GCC GCC&#xff08;GNU Compiler Collection&#xff09;是一个强大且常用的编译器套件&#xff0c;支持多种编程语言&#xff0c;比如 C 和 C。在嵌入式开发中&#xff0c;GCC 可以帮助我们把人类可读的 C/C 代码编译成机器可以理解的二进制…...

Java Agent使用

文章目录 基本使用premain使用场景 agentmain 关于tools.jar https://docs.oracle.com/en/java/javase/20/docs/specs/jvmti.html com.sun的API&#xff0c;如果使用其他厂商的JVM&#xff0c;可能没有这个API了&#xff0c;比如Eclipse的J9 https://www.ibm.com/docs/en/sdk…...

selenium 点击元素报错element not interactable

描述说明&#xff1a; 我这里是获取一个span标签后并点击&#xff0c;用的元素自带的element.click()&#xff0c;报错示例代码如下&#xff1a; driver.find_element(By.XPATH,//span[id"my_span"]).click() # 或者 elementdriver.find_element(By.XPATH,//span[i…...

【大数据技术基础 | 实验七】HBase实验:部署HBase

文章目录 一、实验目的二、实验要求三、实验原理四、实验环境五、实验内容和步骤&#xff08;一&#xff09;验证Hadoop和ZooKeeper已启动&#xff08;二&#xff09;修改HBase配置文件&#xff08;三&#xff09;启动并验证HBase 六、实验结果七、实验心得 一、实验目的 掌握…...

Android进程保活,lmkd杀进程相关

lmk原理 Android进程回收之LowMemoryKiller原理 lmkd 更新进程oomAdj; 设备端进程被杀可能原因...

SDL 播放PCM

SDL2播放PCM使用SDL2播放PCM音频采样数据。SDL实际上是对底层绘图API&#xff08;Direct3D&#xff0c;OpenGL&#xff09;的封装&#xff0c;使用起来明显简单于直接调用底层API。 测试的PCM数据采用采样率44.1k, 采用精度S16SYS, 通道数2 函数调用步骤如下: [初始化]SDL_In…...

基于MPPT最大功率跟踪的光伏发电蓄电池控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于MPPT最大功率跟踪的光伏发电蓄电池控制系统simulink建模与仿真。本系统包括PV模块&#xff0c;电池模块&#xff0c;电池控制器模块&#xff0c;MPPT模块&#xff0c;PWM模…...

深入解析Vue3:从入门到实战(详细版)

文章目录 前言一、Vue3简介官网地址主要特点 二、安装与创建Vue3项目使用Vue CLI创建项目使用Vite创建项目 三、Composition API详解Setup函数ref与Reactive生命周期钩子计算属性和监听器 四、新特性与优化响应式系统更好的TypeScript支持类型定义类型推断新组件全局API重构更好…...

Pr 视频效果:ASC CDL

视频效果/颜色校正/ASC CDL Color Correction/ASC CDL ASC CDL ASC CDL效果通过对红、绿、蓝三个原色通道的独立调整&#xff0c;实现对图像色彩的精确控制。在此基础上&#xff0c;还可用于调整处理后图像的整体饱和度。 ◆ ◆ ◆ 效果选项说明 斜率 Slope、偏移 Offset和功…...

C++ --- Socket套接字的使用

目录 一.什么是Socket套接字&#xff1f; 二.Socket的使用&#xff1a; 前置步骤&#xff1a; 为什么要加入 WSAStartup 和 WSACleanup &#xff1f; 1.创建Socket&#xff1a; 2.绑定Socket&#xff1a; 3.服务端监听连接请求&#xff1a; 4.服务端接受客户端连接&…...

MG协议转换器:制氢行业的数字桥梁

在新能源产业蓬勃发展的今天&#xff0c;制氢行业正迎来前所未有的发展机遇。作为清洁能源的重要组成部分&#xff0c;氢气的生产与利用不仅关乎环境保护&#xff0c;更是推动能源结构转型的关键一环。然而&#xff0c;在制氢行业的数字化转型进程中&#xff0c;数据的传输与处…...

人工智能技术的未来:变革生活与工作的潜力

随着人工智能&#xff08;AI&#xff09;技术的不断发展&#xff0c;我们已经见证了其在各行各业的巨大变革。无论是在医疗、商业还是日常生活中&#xff0c;AI都正在悄然改变着我们的工作方式和生活方式。未来&#xff0c;人工智能的应用前景广阔&#xff0c;它将继续深入我们…...

D60【python 接口自动化学习】- python基础之数据库

day60 数据库定义 学习日期&#xff1a;20241106 学习目标&#xff1a;MySQL数据库-- 128&#xff1a;数据库定义 学习笔记&#xff1a; 无处不在的数据库 数据库如何存储数据 数据库管理系统&#xff08;数据库软件&#xff09; 数据库和SQL的关系 总结 数据库就是指数据…...

零基础大龄程序员如何转型AI大模型,系统学习路径与资源推荐!!

前言 随着科技的飞速发展&#xff0c;AI大模型浪潮席卷全球&#xff0c;相关岗位炙手可热。在这个背景下&#xff0c;许多大龄程序员开始思考如何转型&#xff0c;以适应时代的变化。结合自身编程基础&#xff0c;大龄程序员可以学习机器学习、深度学习算法&#xff0c;投身于…...

vue3+vant实现使用van-picker实现三级级联菜单展示(含递归遍历)

1、递归遍历三级展示&#xff0c;禁用自动弹起软键盘、设置文档自动换行避免过长文本省略号展示 <div class"text_div"><van-fieldclass"span_text":center"true"v-model"jobLevelCodeText"is-linklabel"任职岗位"…...

oracle-函数-grouping sets(x1,x2,x3...)的妙用

GROUPING SETS 允许你为多个列组合生成分组汇总。它类似于多个 GROUP BY 子句的 UNION ALL 操作&#xff0c;但更加简洁和高效 首先&#xff1a;创建表及接入测试数据 create table students (id number(15,0), area varchar2(10), stu_type varchar2(2), score number(20,2))…...

人工智能在医疗病例诊断中的应用与展望

人工智能在医疗病例诊断中的应用与展望 摘要&#xff1a; 本文探讨了人工智能在医疗病例诊断中的卓越应用、显著优势、面临的挑战及应对策略&#xff0c;以及未来展望。人工智能在医学影像诊断、病理诊断和辅助临床诊断方面展现出巨大潜力&#xff0c;为医学研究和临床治疗带来…...

OceanBase 安装使用详细说明

OceanBase 安装使用详细说明 一、系统环境要求二、安装OceanBase环境方案一:在线下载并安装all-in-one安装包方案二:离线安装all-in-one安装包安装前的准备工作三、配置OceanBase集群编辑配置文件部署和启动集群连接到集群集群状态和管理四、创建业务租户和数据库创建用户并赋…...

CI_CD

什么是CI/CD 在前端开发中&#xff0c;CI/CD 是 Continuous Integration&#xff08;持续集成&#xff09;和 Continuous Deployment/Continuous Delivery&#xff08;持续部署/持续交付&#xff09;的简称。它是一种软件开发实践&#xff0c;自动化了应用的构建、测试和发布过…...

Linux -- 初识线程

目录 线程的初步认识 为什么需要线程 怎么让代码分成多个执行流并发执行呢&#xff1f; 管理线程 线程的初步认识 线程是进程内部的一个执行分支&#xff0c;线程是CPU调度的基本单位。 在Linux操作系统中&#xff0c;线程是程序执行流的最小单位。一个进程可以包含多个线…...

Uniapp底部导航栏设置(附带PS填充图标教程)

首先需要注册和登录ifconfont官网&#xff0c;然后创建项目添加需要的图标 创建和添加图标库请参考&#xff1a;Uniapp在Vue环境中引入iconfont图标库&#xff08;详细教程&#xff09; 打开iconfont官网&#xff0c;找到之前添加的图标库&#xff0c;下载png图片 如果需要的…...

单智能体carla强化学习实战工程介绍

有三个工程&#xff1a; Ray_Carla: 因为有的论文用多进程训练强化学习&#xff0c;包括ray分布式框架等&#xff0c;这里直接放了一个ray框架的示例代码&#xff0c;是用sac搭建的&#xff0c;obs没用图像&#xff0c;是数值状态向量值&#xff08;速度那些&#xff09;。 …...

潮玩宇宙方块兽系统开发:可定制UI与多种游戏内嵌助力个性化体验

潮玩宇宙方块兽系统开发正在推动潮玩与游戏的融合&#xff0c;通过个性化的UI设计和多游戏内嵌模式&#xff0c;为用户带来了独一无二的体验。本文将从可定制UI、多游戏内嵌功能以及系统实现等方面入手&#xff0c;探讨如何构建一个极具吸引力的潮玩宇宙方块兽系统。 一、可定制…...

什么是低代码?3000字低代码超全解读!

现在这个时代企业面对的挑战越来越复杂&#xff0c;尤其在软件开发和应用交付方面&#xff0c;因为传统开发过程复杂且费时&#xff0c;企业很难从传统的软件开发方式中迅速响应市场变化从而获利。 而低代码&#xff08;Low-Code&#xff09;平台的出现为企业提供了一种更加快…...

雷池社区版7.1新版本自定义NGINX配置分析

简单介绍雷池&#xff0c;是一款简单好用, 效果突出的 Web 应用防火墙(WAF)&#xff0c;可以保护 Web 服务不受黑客攻击。 雷池通过阻断流向 Web 服务的恶意 HTTP 流量来保护 Web 服务。雷池作为反向代理接入网络&#xff0c;通过在 Web 服务前部署雷池&#xff0c;可在 Web 服…...