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

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 #1155RustCrypto 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=qm+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=xqm 得到余数。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=mxb2kb2k=mxbk+1bk1b2k=mb2kbk1xbk+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+1bk1xmb2k

从而允许 预先、计算

μ = ⌊ 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+1bk1xμ

注意:

  • 运算中的 ⌊ ⋅ b k − 1 ⌋ \lfloor \frac{\cdot}{b^{k-1}} \rfloor bk1 ⌊ ⋅ 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~[q2,q],(将在后面的“分析部分”中详细说明)。这意味着近似商 q ~ \tilde{q} q~ 至多比真实商 q q q 小 2。

3. 在 x ≈ q ~ ⋅ m + r x \approx \tilde{q} \cdot m + r xq~m+r 中计算 r r r

如果我们已经精确计算出 q q q,那么可以直接通过下式计算:
r = x − q ⋅ m r = x - q \cdot m r=xqm

由于 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=xqmmodbk=(xmodbk)(qmmodbk)

(其中模 b k b^k bk 运算在二进制机器上可以高效实现)
在这里插入图片描述

然而,请记住在此计算的是商的近似值 q ~ \tilde{q} q~,且 q ~ ∈ [ q − 2 , q ] \tilde{q} \in [q - 2, q] q~[q2,q]

从而可能有以下三种情况之一:

  • 1)情况1: r = x − q ~ ⋅ m r = x - \tilde{q} \cdot m r=xq~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~=xq~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 2m<2bk

因此,可以对近似值进行上界估计:

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} rr~r+2m<bk+2bk=3bk<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~[q2,q]。本节将展示:在实际中使用的大多数模数中,更紧的界限成立,即 q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~[q1,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+1bk1xmb2k

由于 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} α=xmodbk1,则 α < b k − 1 \alpha < b^{k-1} α<bk1;再设 β = 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}} bk1x=bk1xα

⌊ 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+1bk1xmb2k=bk+1bk1xαmb2kβ=mb2k(xα)(b2kβ)=mxmb2kα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=mbk+1αb2k+β(xα)(注意:z0)

于是有:
q ~ = ⌊ x m − z ⌋ \tilde{q} = \lfloor \frac{x}{m} - {\color{red}{z}} \rfloor q~=mxz

利用floor函数的不等式:
⌊ x ⌋ + ⌊ y ⌋ + 1 ≥ ⌊ x + y ⌋ \lfloor x \rfloor + \lfloor y \rfloor + 1 \ge \lfloor x + y \rfloor x+y+1x+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 mxz+z+1(mxz)+z=mx=q

即等价为:
q ~ + ⌊ z ⌋ + 1 ≥ q \tilde{q} + \lfloor z \rfloor + 1 \ge q q~+z+1q

因此, z z z 的界限对于分析 q ~ \tilde{q} q~ 的界限是关键。如果能证明 0 ≤ z < 2 0 \leq z < 2 0z<2,那么 ⌊ z ⌋ ≤ 1 \left\lfloor z \right\rfloor \leq 1 z1,就能得出:

q ~ + 2 ≥ q ~ + ⌊ z ⌋ + 1 ≥ q \tilde{q} + 2 \ge \tilde{q} + \lfloor z \rfloor + 1 \ge q q~+2q~+z+1q

从而验证更紧的界限。接下来,将分析 z z z 的具体界限。

4.1 证明 q ~ ∈ [ q − 2 , q ] \tilde{q} \in [q - 2, q] q~[q2,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=mb2kαb2k+β(xα)<mb2kbk1b2k+βb2k=mbk1+β

已知 b k − 1 < m b^{k-1} < m bk1<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<mbk1+β<mm+m=2

由此可得:

⌊ z ⌋ ≤ 1 \lfloor z \rfloor \leq 1 z1

这正是所想要的。因此可得出结论:

q ~ + 2 ≥ q ~ + ⌊ z ⌋ + 1 ≥ q \tilde{q} + 2 \geq \tilde{q} + \lfloor z \rfloor + 1 \geq q q~+2q~+z+1q

4.2 实际中的更紧界限: q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~[q1,q]

至此已经证明在所有情况下 q ~ ∈ [ q − 2 , q ] \tilde{q} \in [q - 2, q] q~[q2,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~+1q~+z+1q

接下来来看哪些模数 m m m 满足这个更紧界限。回顾之前的推导:

z < b k − 1 + β m z < \frac{b^{k-1} + \beta}{m} z<mbk1+β

要使 z < 1 z < 1 z<1 成立,需要:

b k − 1 + β ≤ m b^{k-1} + \beta \leq m bk1+βm

即:

β ≤ m − b k − 1 \beta \leq m - b^{k-1} βmbk1

这表示:如果 β ≤ m − b k − 1 \beta \leq m - b^{k-1} βmbk1,那么 z < 1 z < 1 z<1,从而 q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~[q1,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 βmbk1 (where β=b2kmodm), then q~[q1,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} β=b2kmodmmbk1,则 q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~[q1,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} mbk1 通常接近 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} βmbk1 的概率非常高。于是,大多数模数 m m m 都会满足 z < 1 z < 1 z<1,从而得出 q ~ + 1 ≥ q \tilde{q} + 1 \geq q q~+1q

为了量化这种概率,假设常见情况是 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[βmbk1]=mmbk1>1b2

从而有:

  • b = 2 32 b = 2^{32} b=232 时,满足更紧界限的概率超过 1 − 1 2 31 1 - \frac{1}{2^{31}} 12311
  • b = 2 64 b = 2^{64} b=264 时,该概率超过 1 − 1 2 63 1 - \frac{1}{2^{63}} 12631

因此,在实际中几乎所有模数都满足更紧界限 q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~[q1,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} βmbk1,就可以保证计算出的 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} βmbk1,所以更紧的界限 q ~ ∈ [ q − 1 , q ] \tilde{q} \in [q - 1, q] q~[q1,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] [q2,q] 收紧为 [ q − 1 , q ] [q - 1, q] [q1,q]

这一更紧的界限在大多数情况下消除了第二次减法的必要性,从而实现了更快速、更高效的实现。

本文还展示了该优化如何应用于现实中的加密库,如 RustCrypto 的 P-256 标量域实现中,仅删除不必要的减法,就显著提升了性能。这一发现同样适用于其他依赖固定模数的密码系统及零知识证明框架。

参考资料

[1] zkSecurity团队2025年5月1日博客 Optimizing Barrett Reduction: Tighter Bounds Eliminate Redundant Subtractions

http://www.xdnf.cn/news/289873.html

相关文章:

  • 迅睿CMS导入别站数据库
  • 【瞎折腾/mi50 32G/ubuntu】mi50显卡ubuntu运行大模型开坑(二)使用llama.cpp部署Qwen3系列
  • 卡尔曼滤波详解
  • 从Excel到高级工具:数据分析进阶指南
  • # 部署深度学习模型:Flask API 服务端与客户端通信实战
  • Linux进程间的通信
  • Node.js 是什么?
  • docker 外部能访问外网,内部不行(代理问题)
  • SQL常见误区
  • 如何扫描系统漏洞?漏洞扫描的原理是什么?
  • 【MCP Node.js SDK 全栈进阶指南】专家篇(1):MCP-SDK扩展与定制
  • Dify本地 + vllm + Qwen
  • 走出 Demo,走向现实:DeepSeek-VL 的多模态工程路线图
  • 协议(消息)生成
  • qt csv文件写操作
  • 3.5/Q1,GBD数据库最新一区文章解读
  • P3246 [HNOI2016] 序列 Solution
  • 项目生成日志链路id,traceId
  • 数据库的二级索引
  • 【PostgreSQL数据分析实战:从数据清洗到可视化全流程】4.4 异构数据源整合(CSV/JSON/Excel数据导入)
  • 数据结构小扫尾——栈
  • BUUCTF 大流量分析(一) 1
  • 比较两种判断相同二叉树的方法:递归与遍历序列对比
  • 湖北理元理律师事务所:债务法律服务的民生价值重构
  • brep2seq kaggle安装 micromamba conda环境
  • 政务服务智能化改造方案和案例分析
  • QT6 源(79):阅读与注释表盘 QDial 的源码,其是基类QAbstractSlider 的子类,及其刻度线的属性举例
  • 深入理解 CSS Flex 布局:代码实例解析
  • 【Hive入门】Hive安全管理与权限控制:基于SQL标准的授权GRANT REVOKE深度解析
  • kotlin 05flow -从 LiveData 迁移到 Kotlin Flow 完整教程