Barrett Reduction算法优化:更紧的界限消除冗余的减法
1. 引言
Barrett Reduction 是一种被广泛使用的模 m m m 运算算法。在zkSecurity 受NEAR团队所委托的(针对RustCrypto: NIST P-256 (secp256r1) elliptic curve——https://github.com/RustCrypto/elliptic-curves/tree/master/p256)进行的 Rust p256 crate 审计 中分析表明,Barrett Reduction 的误差界限比传统假设的要更紧。对于大多数用于密码学的模(如 NIST 曲线),商的近似误差最多为 1(而不是 2)。这个改进在实际中消除了对第二次减法的需求。通过 采用这一优化——详情见PR p256: remove unnecessary sub in scalar Barrett reduction #1155,RustCrypto p256 在标量乘法中实现了 14% 的性能提升。
2. 什么是 Barrett Reduction?
Barrett Reduction 是一种高效计算除法余数(即模运算 x m o d m x \bmod m xmodm)的方法,它避免了直接除法操作的高昂计算代价。
可将计算 r = x m o d m r = x \bmod m r=xmodm,表示为 x = q ⋅ m + r x = q \cdot m + r x=q⋅m+r,其中 q q q 是商, r r r 是余数。在实际应用中(如密码学中的有限域运算),模 m m m 通常是一个用 k k k 个 limb 表示的大整数。每个 limb 是一个 32 位或 64 位的值(取决于机器字长),从而基数radix b = 2 32 b = 2^{32} b=232 或 2 64 2^{64} 264。而值 x x x 是一个 2 k 2k 2k-limb 的整数,因为它通常来自两个 k k k-limb 整数的乘积。
一种计算 r r r 的方式是先计算:
q = ⌊ x m ⌋ q = \left\lfloor \frac{x}{m} \right\rfloor q=⌊mx⌋
一旦确定了 q q q 值,就可通过 r = x − q ⋅ m r = x - q \cdot m r=x−q⋅m 得到余数。Barrett Reduction 提供了一种更高效的方式来近似计算 q q q,从而避免了昂贵的直接除法。
先将上面的公式重写为:
q = ⌊ x / m ⌋ = ⌊ x m ⋅ b 2 k b 2 k ⌋ = ⌊ x m ⋅ b 2 k b k + 1 ⋅ b k − 1 ⌋ = ⌊ b 2 k m ⋅ x b k − 1 ⋅ 1 b k + 1 ⌋ q = \lfloor x / m \rfloor = \left\lfloor\frac{x}{m} \cdot \frac{b^{2k}}{b^{2k}}\right\rfloor = \left\lfloor\frac{x}{m} \cdot \frac{b^{2k}}{b^{k+1}\cdot b^{k-1}}\right\rfloor = \left\lfloor\frac{b^{2k}}{m} \cdot \frac{x}{b^{k-1}} \cdot \frac{1}{b^{k+1}}\right\rfloor q=⌊x/m⌋=⌊mx⋅b2kb2k⌋=⌊mx⋅bk+1⋅bk−1b2k⌋=⌊mb2k⋅bk−1x⋅bk+11⌋
到目前为止,计算仍是精确的。但在此不打算精确计算 q q q,而是近似计算其值:
q ~ = ⌊ ⌊ x b k − 1 ⌋ ⋅ ⌊ b 2 k m ⌋ b k + 1 ⌋ \tilde{q} = \left\lfloor \frac{{\color{red}{\lfloor}} \frac{x}{b^{k-1}} {\color{red}{\rfloor}} \cdot {\color{red}{\lfloor}} \frac{b^{2k}}{m} {\color{red}{\rfloor}}}{b^{k+1}}\right\rfloor q~=⌊bk+1⌊bk−1x⌋⋅⌊mb2k⌋⌋
从而允许 预先、计算:
μ = ⌊ b 2 k m ⌋ \mu = \left\lfloor \frac{b^{2k}}{m} \right\rfloor μ=⌊mb2k⌋
从而重写为:
q = ⌊ ⌊ x b k − 1 ⌋ ⋅ μ b k + 1 ⌋ q = \left\lfloor \frac{ \left\lfloor \frac{x}{b^{k-1}} \right\rfloor \cdot \mu }{b^{k+1}} \right\rfloor q=⌊bk+1⌊bk−1x⌋⋅μ⌋
注意:
- 运算中的 ⌊ ⋅ b k − 1 ⌋ \lfloor \frac{\cdot}{b^{k-1}} \rfloor ⌊bk−1⋅⌋ 和 ⌊ ⋅ b k + 1 ⌋ \lfloor \frac{\cdot}{b^{k+1}} \rfloor ⌊bk+1⋅⌋ 可以通过右移操作快速实现。
由于两次近似计算可能小于其精确结果,因此有 q ~ ≤ q \tilde{q} \leq q q~≤q。传统分析认为 q ~ ∈ [ q − 2 , q ] \tilde{q} \in [q - 2, q] q~∈[q−2,q],(将在后面的“分析部分”中详细说明)。这意味着近似商 q ~ \tilde{q} q~ 至多比真实商 q q q 小 2。
3. 在 x ≈ q ~ ⋅ m + r x \approx \tilde{q} \cdot m + r x≈q~⋅m+r 中计算 r r r
如果我们已经精确计算出 q q q,那么可以直接通过下式计算:
r = x − q ⋅ m r = x - q \cdot m r=x−q⋅m
由于 r ∈ [ 0 , m ) r \in [0, m) r∈[0,m),这个减法仅涉及 m m m 的比特长度。因此,可以只用最低的 b k b^k bk 位来更快地完成计算:
r = x − q ⋅ m m o d b k = ( x m o d b k ) − ( q ⋅ m m o d b k ) r = x - q \cdot m \mod b^k = (x \bmod b^k) - (q \cdot m \bmod b^k) r=x−q⋅mmodbk=(xmodbk)−(q⋅mmodbk)
(其中模 b k b^k bk 运算在二进制机器上可以高效实现)
然而,请记住在此计算的是商的近似值 q ~ \tilde{q} q~,且 q ~ ∈ [ q − 2 , q ] \tilde{q} \in [q - 2, q] q~∈[q−2,q]。
从而可能有以下三种情况之一:
- 1)情况1: r = x − q ~ ⋅ m r = x - \tilde{q} \cdot m r=x−q~⋅m
- 2)情况2: r = x − ( q ~ + 1 ) ⋅ m r = x - (\tilde{q} + 1) \cdot m r=x−(q~+1)⋅m
- 3)情况3: r = x − ( q ~ + 2 ) ⋅ m r = x - (\tilde{q} + 2) \cdot m r=x−(q~+2)⋅m
为了计算 r r r,首先尝试情况 1。如果结果不小于 m m m,再减去一次或两次 m m m,将结果调整到正确范围内。
这意味着不能保证 r ~ = x − q ~ ⋅ m < b k \tilde{r} = x - \tilde{q} \cdot m < b^k r~=x−q~⋅m<bk 立即成立。相反,值可能比 m m m 或 2 m 2m 2m 更大。
由于 m < b k m < b^k m<bk,可以推出:
2 ⋅ m < 2 ⋅ b k 2 \cdot m < 2 \cdot b^k 2⋅m<2⋅bk
因此,可以对近似值进行上界估计:
r ≤ r ~ ≤ r + 2 m < b k + 2 ⋅ b k = 3 ⋅ b k < b k + 1 r \leq \tilde{r} \leq r + 2m < b^k + 2 \cdot b^k = 3 \cdot b^k < b^{k+1} r≤r~≤r+2m<bk+2⋅bk=3⋅bk<bk+1
接着,可以更高效地计算 r ~ \tilde{r} r~:
r ~ = ( ( x m o d b k + 1 ) − ( q ~ ⋅ m m o d b k + 1 ) ) m o d b k + 1 \tilde{r} = \left( (x \bmod b^{k+1}) - (\tilde{q} \cdot m \bmod b^{k+1}) \right) \bmod b^{k+1} r~=((xmodbk+1)−(q~⋅mmodbk+1))modbk+1
再次强调,模 b k + 1 b^{k+1} bk+1 运算在二进制机器上是非常高效的。
最终,可得出一个与 Handbook of Applied Cryptography 第 14 章 所描述的算法一致的形式。上述步骤与书中描述的过程紧密对应。
4. 更紧的界限分析
近似商 q ~ \tilde{q} q~ 的界限直接决定了需要将 r r r 减去多少次模数 m m m 才能使结果落入正确范围。传统上认为该界限为 q ~ ∈ [ q − 2 , q ] \tilde{q} \in [q - 2, q] q~∈[q−2,q]。本节将展示:在实际中使用的大多数模数中,更紧的界限成立,即 q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~∈[q−1,q]。
回顾定义:
q = ⌊ x m ⌋ q = \left\lfloor \frac{x}{m} \right\rfloor q=⌊mx⌋
q ~ = ⌊ ⌊ x b k − 1 ⌋ ⋅ ⌊ b 2 k m ⌋ b k + 1 ⌋ \tilde{q} = \left\lfloor \frac{\left\lfloor \frac{x}{b^{k-1}} \right\rfloor \cdot \left\lfloor \frac{b^{2k}}{m} \right\rfloor}{b^{k+1}} \right\rfloor q~= bk+1⌊bk−1x⌋⋅⌊mb2k⌋
由于 q ~ \tilde{q} q~ 是通过截断 x m \frac{x}{m} mx 得到的近似值,它自然满足 q ~ ≤ q \tilde{q} \leq q q~≤q。
设 α = x m o d b k − 1 \alpha = x \bmod b^{k-1} α=xmodbk−1,则 α < b k − 1 \alpha < b^{k-1} α<bk−1;再设 β = b 2 k m o d m \beta = b^{2k} \bmod m β=b2kmodm,则 β < m \beta < m β<m。则可以移除floor函数:
⌊ x b k − 1 ⌋ = x − α b k − 1 \left\lfloor \frac{x}{b^{k-1}} \right\rfloor = \frac{x - \alpha}{b^{k-1}} ⌊bk−1x⌋=bk−1x−α
⌊ b 2 k m ⌋ = b 2 k − β m \left\lfloor \frac{b^{2k}}{m} \right\rfloor = \frac{b^{2k} - \beta}{m} ⌊mb2k⌋=mb2k−β
于是可以简化 q ~ \tilde{q} q~ 的表达式:
q ~ = ⌊ ⌊ x b k − 1 ⌋ ⋅ ⌊ b 2 k m ⌋ b k + 1 ⌋ = ⌊ x − α b k − 1 ⋅ b 2 k − β m b k + 1 ⌋ = ⌊ ( x − α ) ⋅ ( b 2 k − β ) m ⋅ b 2 k ⌋ = ⌊ x m − α ⋅ b 2 k + β ⋅ ( x − α ) m ⋅ b 2 k ⌋ \begin{align*} \tilde{q} &= \lfloor \frac{\lfloor \frac{x}{b^{k-1}} \rfloor \cdot \lfloor \frac{b^{2k}}{m} \rfloor}{b^{k+1}} \rfloor\\ &= \lfloor \frac{ \frac{x - \alpha}{b^{k-1}} \cdot \frac{b^{2k} - \beta}{m}}{b^{k+1}} \rfloor \\ &= \lfloor \frac{(x - \alpha) \cdot (b^{2k} - \beta)}{m \cdot b^{2k}} \rfloor \\ &= \lfloor \frac{x}{m} - {\color{red}{\frac{\alpha \cdot b^{2k} + \beta \cdot (x - \alpha)}{m \cdot b^{2k}}}} \rfloor \end{align*} q~=⌊bk+1⌊bk−1x⌋⋅⌊mb2k⌋⌋=⌊bk+1bk−1x−α⋅mb2k−β⌋=⌊m⋅b2k(x−α)⋅(b2k−β)⌋=⌊mx−m⋅b2kα⋅b2k+β⋅(x−α)⌋
用 z {\color{red}{z}} z 表示上述红色部分,即:
z = α ⋅ b 2 k + β ⋅ ( x − α ) m ⋅ b k + 1 (注意: z ≥ 0 ) z = \frac{\alpha \cdot b^{2k} + \beta \cdot (x - \alpha)}{m \cdot b^{k+1}} \quad \text{(注意:\( z \geq 0 \))} z=m⋅bk+1α⋅b2k+β⋅(x−α)(注意:z≥0)
于是有:
q ~ = ⌊ x m − z ⌋ \tilde{q} = \lfloor \frac{x}{m} - {\color{red}{z}} \rfloor q~=⌊mx−z⌋
利用floor函数的不等式:
⌊ x ⌋ + ⌊ y ⌋ + 1 ≥ ⌊ x + y ⌋ \lfloor x \rfloor + \lfloor y \rfloor + 1 \ge \lfloor x + y \rfloor ⌊x⌋+⌊y⌋+1≥⌊x+y⌋
从而有:
⌊ x m − z ⌋ + ⌊ z ⌋ + 1 ≥ ⌊ ( x m − z ) + z ⌋ = ⌊ x m ⌋ = q \lfloor \frac{x}{m} - z \rfloor + \lfloor z \rfloor + 1 \ge \lfloor \left(\frac{x}{m} - z\right) + z \rfloor = \lfloor \frac{x}{m} \rfloor = q ⌊mx−z⌋+⌊z⌋+1≥⌊(mx−z)+z⌋=⌊mx⌋=q
即等价为:
q ~ + ⌊ z ⌋ + 1 ≥ q \tilde{q} + \lfloor z \rfloor + 1 \ge q q~+⌊z⌋+1≥q
因此, z z z 的界限对于分析 q ~ \tilde{q} q~ 的界限是关键。如果能证明 0 ≤ z < 2 0 \leq z < 2 0≤z<2,那么 ⌊ z ⌋ ≤ 1 \left\lfloor z \right\rfloor \leq 1 ⌊z⌋≤1,就能得出:
q ~ + 2 ≥ q ~ + ⌊ z ⌋ + 1 ≥ q \tilde{q} + 2 \ge \tilde{q} + \lfloor z \rfloor + 1 \ge q q~+2≥q~+⌊z⌋+1≥q
从而验证更紧的界限。接下来,将分析 z z z 的具体界限。
4.1 证明 q ~ ∈ [ q − 2 , q ] \tilde{q} \in [q - 2, q] q~∈[q−2,q]
有:
z = α ⋅ b 2 k + β ⋅ ( x − α ) m ⋅ b 2 k < b k − 1 ⋅ b 2 k + β ⋅ b 2 k m ⋅ b 2 k = b k − 1 + β m \begin{align*} z &= \frac{\alpha \cdot b^{2k} + \beta \cdot (x-\alpha)}{m \cdot b^{2k}} \\ &\lt \frac{{\color{red}{b^{k-1}}} \cdot b^{2k} + \beta \cdot {\color{red}{b^{2k}}}}{m\cdot b^{2k}} \\ &= \frac{b^{k-1} + \beta}{m} \end{align*} z=m⋅b2kα⋅b2k+β⋅(x−α)<m⋅b2kbk−1⋅b2k+β⋅b2k=mbk−1+β
已知 b k − 1 < m b^{k-1} < m bk−1<m(因为 m m m 是一个 k k k-limb 整数),且 β < m \beta < m β<m,因此:
z < b k − 1 + β m < m + m m = 2 z < \frac{b^{k-1} + \beta}{m} < \frac{m + m}{m} = 2 z<mbk−1+β<mm+m=2
由此可得:
⌊ z ⌋ ≤ 1 \lfloor z \rfloor \leq 1 ⌊z⌋≤1
这正是所想要的。因此可得出结论:
q ~ + 2 ≥ q ~ + ⌊ z ⌋ + 1 ≥ q \tilde{q} + 2 \geq \tilde{q} + \lfloor z \rfloor + 1 \geq q q~+2≥q~+⌊z⌋+1≥q
4.2 实际中的更紧界限: q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~∈[q−1,q]
至此已经证明在所有情况下 q ~ ∈ [ q − 2 , q ] \tilde{q} \in [q - 2, q] q~∈[q−2,q]。然而,这是一个较为宽松的界限。这里进一步说明,在实际中使用的大多数模数 m m m 下,可以得到一个更紧的界限:即 z < 1 z < 1 z<1,从而:
q ~ + 1 ≥ q ~ + ⌊ z ⌋ + 1 ≥ q \tilde{q} + 1 \geq \tilde{q} + \lfloor z \rfloor + 1 \geq q q~+1≥q~+⌊z⌋+1≥q
接下来来看哪些模数 m m m 满足这个更紧界限。回顾之前的推导:
z < b k − 1 + β m z < \frac{b^{k-1} + \beta}{m} z<mbk−1+β
要使 z < 1 z < 1 z<1 成立,需要:
b k − 1 + β ≤ m b^{k-1} + \beta \leq m bk−1+β≤m
即:
β ≤ m − b k − 1 \beta \leq m - b^{k-1} β≤m−bk−1
这表示:如果 β ≤ m − b k − 1 \beta \leq m - b^{k-1} β≤m−bk−1,那么 z < 1 z < 1 z<1,从而 q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~∈[q−1,q]。可以将其形式化为更紧界限准则:
Given a modulus m , if β ≤ m − b k − 1 (where β = b 2 k m o d m ), then q ~ ∈ [ q − 1 , q ] . \boxed{\text{Given a modulus } m \text{, if } \beta \le m - b^{k-1} \text{ (where } \beta = b^{2k} \bmod{m}\text{), then } \tilde{q} \in [q-1, q] \text{.}} Given a modulus m, if β≤m−bk−1 (where β=b2kmodm), then q~∈[q−1,q].
给定模数 m m m,若满足 β = b 2 k m o d m ≤ m − b k − 1 \beta = b^{2k} \bmod m \leq m - b^{k-1} β=b2kmodm≤m−bk−1,则 q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~∈[q−1,q]。
需要注意的是: β = b 2 k m o d m ∈ [ 0 , m ) \beta = b^{2k} \bmod m \in [0, m) β=b2kmodm∈[0,m)。在实际中, b b b 通常为 2 32 2^{32} 232 或 2 64 2^{64} 264,而 m m m 通常接近 b k b^k bk,因此 m − b k − 1 m - b^{k-1} m−bk−1 通常接近 m m m 本身。
而且, β = b 2 k m o d m \beta = b^{2k} \bmod m β=b2kmodm 对于随机模数 m m m 的分布近似于在区间 [ 0 , m ) [0, m) [0,m) 上的均匀分布,因此 β ≤ m − b k − 1 \beta \leq m - b^{k-1} β≤m−bk−1 的概率非常高。于是,大多数模数 m m m 都会满足 z < 1 z < 1 z<1,从而得出 q ~ + 1 ≥ q \tilde{q} + 1 \geq q q~+1≥q。
为了量化这种概率,假设常见情况是 b k 2 < m < b k \frac{b^k}{2} < m < b^k 2bk<m<bk,且 β \beta β 在 [ 0 , m ) [0, m) [0,m) 上均匀分布,那么:
Pr [ β ≤ m − b k − 1 ] = m − b k − 1 m > 1 − 2 b \Pr[\beta \leq m - b^{k-1}] = \frac{m - b^{k-1}}{m} > 1 - \frac{2}{b} Pr[β≤m−bk−1]=mm−bk−1>1−b2
从而有:
- 当 b = 2 32 b = 2^{32} b=232 时,满足更紧界限的概率超过 1 − 1 2 31 1 - \frac{1}{2^{31}} 1−2311
- 当 b = 2 64 b = 2^{64} b=264 时,该概率超过 1 − 1 2 63 1 - \frac{1}{2^{63}} 1−2631
因此,在实际中几乎所有模数都满足更紧界限 q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~∈[q−1,q]。
直观解释是这样的: μ = ⌊ b 2 k m ⌋ \mu = \left\lfloor \frac{b^{2k}}{m} \right\rfloor μ=⌊mb2k⌋ 是 b 2 k ÷ m b^{2k} \div m b2k÷m 的商,而 β \beta β 是其余数。如果 β \beta β 很小,那么 μ \mu μ 非常接近实际的商,从而计算 q ~ \tilde{q} q~ 时的近似误差就很小。本分析表明:只要 β ≤ m − b k − 1 \beta \leq m - b^{k-1} β≤m−bk−1,就可以保证计算出的 q ~ \tilde{q} q~ 最多比 q q q 小 1。而这个对 β \beta β(或 m m m)的要求相当宽松,因此大多数模数都满足这个更紧的界限。
5. Barrett 除法在实际实现中的优化
更紧的界限使得 Barrett 除法的实现更加高效。根据传统分析,为了使结果落入正确范围,可能需要将 r r r 减去模数 m m m 两次。而对于一个给定的模数 m m m,如果满足更紧的界限条件,那么最多只需减一次 m m m,这意味着可以节省一次减法操作。
这对于常数时间实现尤为重要,因为常数时间实现通常会总是执行最多次数的减法。如,在 RustCrypto 的 P-256 标量域实现 中,始终执行两次减法:
pub(super) const fn barrett_reduce(lo: U256, hi: U256) -> U256 {[...]let r1 = [a0, a1, a2, a3, a4];let r2 = q3_times_n_keep_five(&q3);let r = sub_inner_five(r1, r2);// Result is in range (0, 3*n - 1),// and 90% of the time, no subtraction will be needed.let r = subtract_n_if_necessary(r);let r = subtract_n_if_necessary(r);U256::new([r[0], r[1], r[2], r[3]])
}
由于 P-256 的标量域满足 β ≤ m − b k − 1 \beta \leq m - b^{k-1} β≤m−bk−1,所以更紧的界限 q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~∈[q−1,q] 成立。这意味着计算得到的 q ~ \tilde{q} q~ 最多只比真实商 q q q 小 1。
也就是说,为了得到最终结果,最多只需要将 r r r 减去一次 m m m。因此,以上代码中的第二次 subtract_n_if_necessary
调用是不必要的,可以安全地删除,从而提升运行效率。
基准测试显示,仅仅去掉第二次减法操作,就可以使乘法和求逆的性能提升 14%。
scalar operations/multime: [38.900 ns 38.957 ns 39.026 ns]change: [-14.379% -14.052% -13.734%] (p = 0.00 < 0.05)Performance has improved.
scalar operations/inverttime: [20.716 µs 20.758 µs 20.823 µs]change: [-14.817% -14.331% -13.969%] (p = 0.00 < 0.05)Performance has improved.
如前一节分析所示,更紧的界限在几乎所有模数中都成立。因此,这项优化适用于大多数固定模数的 Barrett 除法实现(如用于椭圆曲线加密 ECC、零知识证明 ZKP)。
以下是一个 Python 脚本,用于测试某个模数 m m m 是否满足更紧的界限:
# Barrett 除法的更紧界限判断准则def tighter_bound_criterion(m):def inner_test(m, b):# 选择 k,使得 b^{k-1} < m < b^kk = 1while b**k < m:k += 1print("k = ", k)beta = b**(2*k) % m# 判断是否满足更紧的界限return beta <= m - b**(k-1)# 同时测试 b=2^32 和 b=2^64return inner_test(m, 2**32) and inner_test(m, 2**64)# P-256 标量域
assert(tighter_bound_criterion(0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551) == True)# P-256 基域
assert(tighter_bound_criterion(0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff) == True)
6. 结论
本分析表明:在实际使用的大多数模数中,对商的近似值 q ~ \tilde{q} q~ 的误差界限可以从传统的 [ q − 2 , q ] [q - 2, q] [q−2,q] 收紧为 [ q − 1 , q ] [q - 1, q] [q−1,q]。
这一更紧的界限在大多数情况下消除了第二次减法的必要性,从而实现了更快速、更高效的实现。
本文还展示了该优化如何应用于现实中的加密库,如 RustCrypto 的 P-256 标量域实现中,仅删除不必要的减法,就显著提升了性能。这一发现同样适用于其他依赖固定模数的密码系统及零知识证明框架。
参考资料
[1] zkSecurity团队2025年5月1日博客 Optimizing Barrett Reduction: Tighter Bounds Eliminate Redundant Subtractions
相关文章:
Barrett Reduction算法优化:更紧的界限消除冗余的减法
1. 引言 Barrett Reduction 是一种被广泛使用的模 m m m 运算算法。在zkSecurity 受NEAR团队所委托的(针对RustCrypto: NIST P-256 (secp256r1) elliptic curve——https://github.com/RustCrypto/elliptic-curves/tree/master/p256)进行的 Rust p256 …...
Node.js 是什么?
Node.js 是什么? Node.js 是一个基于 Chrome V8 JavaScript 引擎 的 跨平台 JavaScript 运行时环境,用于在服务器端运行 JavaScript 代码。它使开发者能够使用 JavaScript 编写后端(服务端)程序,而不仅仅局限于浏览器端(前端)。 1. Node.js 的核心特点 (1) 基于 Chrom…...
数据结构中 数组、链表、图的概念
数据结构是计算机存储、组织数据的方式,数组、链表和图是三种常见的数据结构,下面为你详细介绍它们的概念: 数组 数组是一种线性数据结构,它由一组相同类型的元素组成,这些元素存储在连续的内存位置上。每个元素都可…...
基于PPO的自动驾驶小车绕圈任务
1.任务介绍 任务来源: DQN: Deep Q Learning |自动驾驶入门(?) |算法与实现 任务原始代码: self-driving car 在上一篇使用了DDPG算法完成自动驾驶小车绕圈任务之后,继续学习了PPO算法&…...
Three.js + React 实战系列 - 客户评价区细解教程 Clients 组件✨(回答式评价 + 评分星级)
对个人主页设计和实现感兴趣的朋友可以订阅我的专栏哦!!谢谢大家!!! 在这篇博客中,我们将实现一个简洁的 Hear from My Clients 客户评价区域。这个区块在个人主页中可以突显用户体验和专业度,帮…...
2048游戏(含Python源码)
前言 相关参考游戏: 像素飞机大战(含Python源码)-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/147693018?spm1001.2014.3001.5501使用DeepSeek定制Python小游戏——以“俄罗斯方块”为例-CSDN博客https://blog.csdn.n…...
百度golang开发一面
讲一下数据库的事务机制?acid特性是靠什么实现的? 持久性 redo log 原子性 undo log 隔离性 MVCC或next-lock锁 四个隔离级别是什么,分别解决什么问题? 可串行化实现原理 mysql锁机制?介绍锁的类型,以及原理…...
【Springboot知识】Springboot计划任务Schedule详解
文章目录 Spring Boot 定时任务从原理到实现详解一、核心原理分析1. 架构分层2. 核心组件3. 线程模型 二、基础实现步骤1. 添加依赖2. 主类配置3. 定时任务类 三、高级配置技巧1. 自定义线程池2. 动态配置参数3. 分布式锁集成(Redis示例) 四、异常处理机…...
大模型推理--从零搭建大模型推理服务器:硬件选购、Ubuntu双系统安装与环境配置
自从大模型火了之后就一直想自己组装一台机器去深入研究一下大模型,奈何囊中羞涩,迟迟也没有行动。在下了很大的勇气之后,终于花了接近4万块钱组装了一台台式机,下面给大家详细介绍一下我的装机过程。 1.硬件配置 研究了一周&am…...
如何使用QWidgets设计一个类似于Web Toast的控件?
如何使用QWidgets设计一个类似于Web Toast的控件? 前言 笔者这段时间沉迷于给我的下位机I.MX6ULL做桌面,这里抽空更新一下QT的东西。这篇文章是跟随CCMoveWidget一样的文章,尝试分享自己如何书写这份代码的思考的过程,和笔者…...
博图V20编译报错:备不受支持,无法编译。请更改为受支持的设备。
使用高版本博图打开低版本博图的工程文件时,hmi编译报错不通过,报错提示:备不受支持,无法编译。请更改为受支持的设备。 原因:当前版本的博图软件没有或不支持该组态设备的固件版本。 解决办法:1、安装报错…...
凸性(Convexity)
凸性(Convexity)是一个跨学科的重要概念,广泛应用于数学、优化理论、金融等领域。其核心含义是描述某种结构(如函数、集合)在特定条件下的“无凹陷”性质。 1. 数学中的凸性 1.1 凸函数与凹函数 在数学分析中&#…...
Vuex使用指南:状态管理
一、什么是状态管理?为什么需要 Vuex? 1. 状态管理的基本概念 在 Vue 应用中,状态指的是应用中的数据。例如: 用户登录状态购物车中的商品文章列表的分页信息 状态管理就是对这些数据的创建、读取、更新和删除进行有效管理。 …...
kotlin中枚举带参数和不带参数的区别
一 ✅ 代码对比总结 第一段(带参数 工具方法) enum class SeatPosition(val position: Int) {DRIVER_LEFT(0),DRIVER_RIGHT(1),SECOND_LEFT(2),SECOND_RIGHT(3);companion object {fun fromPosition(position: Int): SeatPosition? {return SeatPosi…...
【Python】Python好玩的第三方库之二维码生成,操作xlsx文件,以及音频控制器
前言 🌟🌟本期讲解关于python的三种第三方库的使用介绍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆那么…...
VTK 交互类介绍
基本概念 交互器(Interactor): 处理用户输入事件的基础类 交互样式(InteractorStyle): 定义具体的交互行为 Widgets: 可交互的UI组件,如滑块、按钮等 Picker: 用于选择场景中的对象 常用交互类 类名功能描述vtkRenderWindowInteractor渲染窗口交互器vtkInteractorStyle交互样式…...
在Window10 和 Ubuntu 24.04LTS 上 Ollama 在线或离线安装部署
Ollama 是一个开源的大型语言模型(LLM)服务框架,旨在通过轻量化、跨平台的设计,简化大模型在本地环境中的部署与应用。其基于 Go 语言开发,通过 Docker 容器化技术封装模型运行环境,提供类似命令行工具的交…...
语音合成之十一 提升TTS语音合成效果:低质量数据清洗、增强与数据扩增
低质量数据清洗、增强与数据扩增 1. 引言:TTS的基石——数据质量2. 基础:TTS数据准备工作流2.1 规划:定义蓝图2.2 执行:从原始数据到训练就绪格式2.3 最佳实践与可复现性 3. 攻克缺陷:低质量语音数据的清洗与增强3.2 手…...
RGB三原色
本文来源 : 腾讯元宝 RGB三原色(红绿蓝)详解 RGB(Red, Green, Blue)是光学的三原色,通过不同比例的混合可以产生人眼可见的绝大多数颜色。它是现代显示技术(如屏幕、投影仪)…...
BUUCTF 大流量分析(一) 1
BUUCTF:https://buuoj.cn/challenges 文章目录 题目描述:密文:解题思路:flag: 相关阅读 CTF Wiki BUUCTF:大流量分析(一) 题目描述: 某黑客对A公司发动了攻击,以下是一段时间内我们…...
虚幻引擎5-Unreal Engine笔记之显卡环境设置使开发流畅
虚幻引擎5-Unreal Engine笔记之显卡环境设置使开发流畅 code review! 文章目录 虚幻引擎5-Unreal Engine笔记之显卡环境设置使开发流畅1.电源管理2.显卡优先设置3.拯救者支持FnQ性能模式切换,建议开发前切至“野兽模式”或高性能模式。4.NVIDIA 驱动设置5.VS2022中…...
suna工具调用可视化界面实现原理分析(一)
这是一个基于React构建的工具调用侧边面板组件,主要用于展示和管理自动化工具调用流程。以下是代码功能解析及关键组件分析: 一、核心功能模块 多工具视图切换系统 • 动态视图加载:通过getToolView函数根据工具名称(如execute-c…...
【将你的IDAPython插件迁移到IDA 9.x:核心API变更与升级指南】
文章目录 将你的 IDAPython 插件迁移到 IDA 9.x:核心 API 变更与升级指南为什么 API 会变化?关键不兼容性一:数据库信息访问 (inf_structure)关键不兼容性二:窗口/视图类型判断 (BWN_* 和 form_type)其他可能的 API 变更迁移策略建…...
《Python星球日记》第31天:Django 框架入门
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏:《Python星球日记》,限时特价订阅中ing 目录 一、Django…...
读《人生道路的选择》有感
读完戴维坎贝尔的《人生道路的选择》,深有感触,虽然只有短短的108也,但作者强调了在复杂的生活环境之中“选择”的重要性。这也是我想要探讨的话题,选择到底会对我们人生产生怎样的影响。 在我们人生当中,确实有许多的…...
opencv+opencv_contrib+cuda和VS2022编译
本文介绍使用OpenCV和OpenCV_Contrib源码及Cuda进行编译的过程,编译过程中会用到OpenCV、OpenCV_Contrib、Toolkit、Cmake、VS2022等工具,最终编译OpenCV的Cuda版本。 一、OpenCV下载地址 OpenCV官网下载地址:https://opencv.org/releases/#࿰…...
STC单片机与淘晶驰串口屏通讯例程之01【新建HDMI工程】
大家好,我是『芯知识学堂』的SingleYork,今天笔者给大家一起学习这款“SYK-0806-A2S1”控制板与淘晶驰串口屏通讯的例程,本例使用的是淘晶驰的4.3寸电阻触摸屏TJC4827T143_011R_I_P20,分辨率为480272,详细参数大家可以查看这个屏的手册。 先来看下本例程整体的效果: 那么…...
PE文件结构(导出表)
导出表 什么是导出表? 导出表是PE文件中记录动态链接库(DLL)对外提供的函数或数据的列表,包含函数名称、序号和内存地址等信息,供其他程序调用 我们写一个dll来查看一下导出函数 int exportFunc1(int a, int b) {ret…...
网络安全自动化:精准把握自动化边界,筑牢企业安全防
在当今数字化时代,网络攻击的威胁日益严峻,企业网络安全的重要性不言而喻。随着海量资产与复杂架构的出现,网络安全自动化成为了众多企业关注的焦点。网络安全维护看似简单的修补系统、删除旧账户、更新软件,在大型企业中却极易变…...
实战设计模式之中介者模式
概述 中介者模式是一种强大且灵活的设计模式,适用于需要优化对象间通信的场景。中介者模式通过引入一个中介对象,来封装一系列对象之间的交互。在没有中介者的情况下,这些对象之间可能会直接相互引用,导致系统中的类紧密耦合&…...
价格识别策略思路
该策略是一种基于价格形态和市场条件的交易算法,旨在通过识别特定的价格模式来生成买入和卖出信号。 价格形态识别 策略的核心在于识别价格的高点和低点形态。通过比较当前周期及其前几个周期的最高价和最低价, 策略定义了一系列条件来判断价格是否形成了…...
Kotlin带接收者的Lambda介绍和应用(封装DialogFragment)
先来看一个具体应用:假设我们有一个App,App中有一个退出应用的按钮,点击该按钮后并不是立即退出,而是先弹出一个对话框,询问用户是否确定要退出,用户点了确定再退出,点取消则不退出,…...
【NLP】32. Transformers (HuggingFace Pipelines 实战)
🤖 Transformers (HuggingFace Pipelines 实战) 本教程基于 Hugging Face 的 transformers 库,展示如何使用预训练模型完成以下任务: 情感分析(Sentiment Analysis)文本生成(Text …...
[ 设计模式 ] | 单例模式
单例模式是什么?哪两种模式? 单例模式就是一个类型的对象,只有一个,比如说搜索引擎中的索引部分,360安全卫士的桌面悬浮球。 饿汉模式和懒汉模式:饿汉模式是线程安全的,懒汉模式不是线程安全的…...
用网页显示工控仪表
一.起因 现在工控也越来越多的使用web页面来显示电压,电流,温度,转速等物理量.本例使用js控制网页显示速度仪表. 二.代码 <html> <head><script type"text/javascript">var ctx;var px0;var movePoint{x0:0,x1:0};function init(){drawFace();m…...
Spring项目改造Solon版,使用体验,对比
概述 对于Solon有些人可能并不了解,在官方概述中,称其是新一代Java企业级应用开发框架,从零开始构建,有自主的标准规范与开放生态。近16万行代码。 并有更快、更小、更简单的特点 什么样的Java项目用Solon好? 按正常…...
2.CFD 计算过程概述:Fluent在散热计算中的优势
1.主流散热软件 2.电子产品热设计的基本要求 3.失效率与温度之间的关系 4.电子产品热设计的基本要求 5.电子产品必须要做散热设计 6.主动散热与被动散热 7.高效山热方案 8.热交换模型 9.Fluent中传热模型...
【Java ee初阶】多线程(6)
一、阻塞队列 队列的原则:“先进先出”,队列分为普通队列,优先级队列等等。在数据结构中,堆是特殊的完全二叉树,一定不要把堆和二叉搜索树混淆。 阻塞队列是一种特殊的队列,也遵循“先进先出”的原则。 …...
Unity:Surface Effector 2D(表面效应器 2D)
目录 什么是表面效应器 2D? 🎯 它是做什么的? 🧪 从第一性原理解释它是怎么工作的 📦 重要参数解释 为什么不直接用 Rigidbody(刚体)来控制运动 ? 所以什么时候该用哪个&#…...
Spring 框架的底层原理
Spring 框架的底层原理主要包括以下几个方面: 核心容器(IoC 容器) IoC(控制反转)原理 : 依赖注入(DI) :这是 IoC 的实现方式之一。在传统的程序开发中,程序组…...
【Unity】AssetBundle热更新
1.新建两个预制体: Cube1:GameObject Material1:Material Cube1使用了Material1材质 之后设置打包配置 Cube1的打包配置为custom.ab Material1的打包配置为mat.ab 2.在Asset文件夹下创建Editor文件夹,并在Editor下创建BuildBundle…...
【算法笔记】动态规划基础(二):背包dp
目录 01背包例题状态表示状态计算初始化AC代码 完全背包例题状态表示状态计算初始化TLE代码 多重背包例题状态表示状态计算初始化AC代码 分组背包例题状态表示状态计算初始化AC代码 二维费用背包例题状态表示状态计算初始化AC代码 混合背包问题例题状态表示状态计算初始化TLE代…...
IP属地是我的定位吗?——解析两者区别
在互联网时代,我们经常看到社交媒体、论坛或APP上显示用户的“IP属地”,许多人会疑惑:IP属地是不是我的精确定位?它会不会暴露我的隐私? 本文将详细解析IP属地和定位的区别,并解答常见的相关问题&#…...
力扣每日一题1128等价多米诺骨牌对的数量
1128. 等价多米诺骨牌对的数量 题目: 给你一组多米诺骨牌 dominoes 。 形式上,dominoes[i] [a, b] 与 dominoes[j] [c, d] 等价 当且仅当 (a c 且 b d) 或者 (a d 且 b c) 。即一张骨牌可以通过旋转 0 度或 180 度得到另一张多米诺骨牌。 在 0 &l…...
SpringBoot集成CXF框架,实现WebService
SpringBoot官网地址:https://spring.io/projects/spring-ws 1、WebService服务端搭建 Maven依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.17&…...
android-ndk开发(2): macOS 安装 ndk
android-ndk开发(2): macOS 安装 ndk 2025/05/05 1. 概要 对于 android-ndk 在 r23 之前的版本,官方提供了 .zip 文件, 解压即安装。 对于 android-ndk 在 r23 以及之后的版本, 官方只提供了 .dmg 文件, 不能简单的解压完成安…...
科创大赛——知识点复习【c++】——第一篇
目录 输入 一、cin 二、scanf 三、gets 四、getchar 五、fgets 输出 一、cout 二、printf 基本数据类型 一,数据类型有哪些? 二,整型(Integer Types) 1,修饰符 2,整型数据的数据范…...
硬件工程师面试常见问题(14)
第六十六问:运放--输入偏置电流和输入失调电流 输入偏置电流lb:是由于运放两个输入极都有漏电流的存在。实际的运放,会有电流流入运放的输入端的。那么输入偏置电流就定义这两个电流的平均值。 输入失调电流 Ios:定义为两个差分输入端偏置电…...
Flink流水线任务在线演示
Flink流水线在线演示 1. 登录系统 访问系统登录页面,输入账号密码完成身份验证。 2. 创建任务 入口:通过顶部菜单栏选择 任务开发,或通过快捷入口 快速创建任务。 任务类型:选择 FlinkPipeline。 3. 配置任务 进入配置界面…...
C++笔记之接口`Interface`
C++笔记之接口Interface code review! 一个简洁简短的 C++ 接口实现示例: #include <iostream>// 1. 定义接口(抽象类) class Shape {public:...