Baby-Step Giant-Step Homomorphic DFT

参考文献:

  1. [CT65] Cooley J W, Tukey J W. An algorithm for the machine calculation of complex Fourier series[J]. Mathematics of computation, 1965, 19(90): 297-301.
  2. [Shoup95] Shoup V. A new polynomial factorization algorithm and its implementation[J]. Journal of Symbolic Computation, 1995, 20(4): 363-397.
  3. [CHKKS18] Cheon J H, Han K, Kim A, et al. Bootstrapping for approximate homomorphic encryption[C]//Advances in Cryptology–EUROCRYPT 2018: 37th Annual International Conference on the Theory and Applications of Cryptographic Techniques, Tel Aviv, Israel, April 29-May 3, 2018 Proceedings, Part I 37. Springer International Publishing, 2018: 360-384.
  4. [CHH18] Cheon J H, Han K, Hhan M. Faster homomorphic discrete fourier transforms and improved fhe bootstrapping[J]. Cryptology ePrint Archive, 2018.
  5. Nussbaumer Transform 以及 Amortized FHEW bootstrapping
  6. Chimera:混合的 RLWE-FHE 方案
  7. 快速乘法技巧:Karatsuba, Toom, Good, Schonhage, Strassen, Nussbaumer
  8. Paterson-Stockmeyer 多项式求值算法

文章目录

  • Baby-Step Giant-Step
    • Shoup95
    • CT65
    • CHKKS18
  • Faster Homomorphic DFT
    • Sparse-Diagonal matrix Factorization
    • Radix-r
    • Hybrid method
    • Result

Baby-Step Giant-Step

Shoup95

文章 [Shoup95] 研究并实现了 BSGS factoring method,用于将单变元多项式分解为不可约因子。其中使用了 CRT 和 FFT 来表示多项式(比 GHS12 的 Doube-CRT 更早) ,并且实现了多项式的快速乘法、除法、逆元、平方、GCD 等等运算。

多项式分解可以分为三步,

  1. square-free factorization:将多项式分解为 f = ∏ i f i f = \prod_i f_i f=ifi,其中的 f i f_i fi 是平方自由的
  2. distinct-degree factorization:将平方自由多项式分解为 f i = ∏ j f i , j f_i = \prod_j f_{i,j} fi=jfi,j,其中的 f i , j f_{i,j} fi,j 是一些度数都为 j j j 的不可约因式的乘积
  3. equal-degree factorization:将不可约因式都是相同度数的平方自由多项式 f i , j f_{i,j} fi,j,分解为这些不可约多项式

主要步骤集中在 step 2,[Shoup95] 观察到事实:对于任意的非负整数 a , b ∈ Z + a,b \in \mathbb Z^+ a,bZ+,多项式 h a , b ( x ) = x p a − x p b ∈ G F ( p ) [ x ] h_{a,b}(x) = x^{p^a} - x^{p^b} \in GF(p)[x] ha,b(x)=xpaxpbGF(p)[x] 以所有的满足 deg ⁡ f ∣ ( a − b ) \deg f|(a-b) degf(ab) 的不可约多项式 f f f 为因式。

对于 deg ⁡ f ≤ n \deg f \le n degfn 的平方自由多项式,它的真因子度数不超过 n / 2 n/2 n/2,我们令 f d , 1 ≤ d ≤ n f_d,1 \le d \le n fd,1dn 是它的全部 d d d 次不可约因子的乘积。我们可以枚举全部的 1 ≤ a − b ≤ n 1\le a-b\le n 1abn,计算出 h a , b ( x ) h_{a,b}(x) ha,b(x),再计算 gcd ⁡ ( h a , b , f ) \gcd(h_{a,b},f) gcd(ha,b,f) 从而获得这些 f d f_d fd

[Shoup95] 使用 BSGS 算法来计算这些 h a , b h_{a,b} ha,b,设置真因子的度数上界 B B B,将它分为 B = l ⋅ m B=l \cdot m B=lm,Baby-Step 就是 { i : 1 ≤ i ≤ l } \{i:1 \le i \le l\} {i:1il},Giant-Step 就是 { l ⋅ j : 1 ≤ j ≤ m } \{l \cdot j:1 \le j \le m\} {lj:1jm}

在这里插入图片描述

然而,如果简单地直接计算 h i , H j h_i,H_j hi,Hj,上述算法依旧是不实用的。[Shoup95] 以迭代的方式计算它们: h i + 1 = h i ( h 1 ) ( m o d f ) h_{i+1} = h_i(h_1) \pmod f hi+1=hi(h1)(modf) H j + 1 = H j ( H 1 ) ( m o d f ) H_{j+1} = H_j(H_1) \pmod f Hj+1=Hj(H1)(modf),现在的问题是如何快速计算这些 modular-composition,形如 g ( h ) ( m o d f ) g(h) \pmod f g(h)(modf)

[Shoup95] 依旧采取 BSGS 算法(类似于 [PS73] 多项式求值算法),选取参数 t ≈ n t \approx \sqrt n tn ,预计算 h i ( m o d f ) , 0 ≤ i ≤ t h^i \pmod f, 0 \le i \le t hi(modf),0it 表格,那么:
g ( x ) = ∑ j = 0 n / t g j ( x ) ⋅ y j , y = x t , deg ⁡ g j < t g(x) = \sum_{j=0}^{n/t} g_j(x) \cdot y^j,\,\, y=x^t,\,\, \deg g_j < t g(x)=j=0n/tgj(x)yj,y=xt,deggj<t
于是,直接使用预计算表的内容,简单计算加法(以及数乘),
g j ( h ) = ∑ i = 0 t g j , i ⋅ h i ( m o d f ) g_j(h) = \sum_{i=0}^t g_{j,i} \cdot h^i \pmod f gj(h)=i=0tgj,ihi(modf)
接着,采取 Horner 法则,计算出
g ( x ) = ( ( g n / t ⋅ h t + ⋯ ) ⋅ h t + g 1 ) ⋅ h t + g 0 g(x) = ((g_{n/t} \cdot h^t + \cdots)\cdot h^t +g_1)\cdot h^t + g_0 g(x)=((gn/tht+)ht+g1)ht+g0
其中的多项式运算都是以 Double-CRT 方式计算的,总的复杂度为 O ( n 2.5 + n log ⁡ n log ⁡ log ⁡ n log ⁡ p ) O(n^{2.5}+n \log n \log\log n\log p) O(n2.5+nlognloglognlogp)

CT65

[CT65] 给出了递归形式的 DFT 分解,其实也是可以视为一种 BSGS 版本的 FFT 算法。DFT 公式为:
A j : = ∑ k = 0 N − 1 a k ⋅ ζ j k A_j := \sum_{k=0}^{N-1} a_k \cdot \zeta^{jk} Aj:=k=0N1akζjk
采取 BSGS 算法,分解为 N = N 1 ⋅ N 2 N=N_1 \cdot N_2 N=N1N2,设置索引
j : = N 1 ⋅ j 1 + j 0 , j 0 ∈ [ N 1 ] , j 1 ∈ [ N 2 ] k : = N 2 ⋅ k 1 + k 0 , k 0 ∈ [ N 2 ] , k 1 ∈ [ N 1 ] \begin{aligned} j &:= N_1 \cdot j_1 + j_0,\,\, j_0 \in [N_1], j_1 \in [N_2]\\ k &:= N_2 \cdot k_1 + k_0,\,\, k_0 \in [N_2], k_1 \in [N_1]\\ \end{aligned} jk:=N1j1+j0,j0[N1],j1[N2]:=N2k1+k0,k0[N2],k1[N1]
那么有
A j 1 , j 0 : = ∑ k 0 ∈ [ N 2 ] ∑ k 1 ∈ [ N 1 ] a k 1 , k 0 ⋅ ζ j k = ∑ k 0 ∈ [ N 2 ] ( ∑ k 1 ∈ [ N 1 ] a k 1 , k 0 ⋅ ζ N 2 j k 1 ) ⋅ ζ j k 0 = ∑ k 0 ∈ [ N 2 ] ( ∑ k 1 ∈ [ N 1 ] a k 1 , k 0 ⋅ ζ N 2 j k 1 ) ⋅ ζ j 0 k 0 ⋅ ζ N 1 j 1 k 0 \begin{aligned} A_{j_1,j_0} &:= \sum_{k_0 \in [N_2]} \sum_{k_1 \in [N_1]} a_{k_1,k_0} \cdot \zeta^{jk}\\ &= \sum_{k_0 \in [N_2]} \left(\sum_{k_1 \in [N_1]} a_{k_1,k_0} \cdot \zeta^{N_2jk_1}\right) \cdot \zeta^{jk_0}\\ &= \sum_{k_0 \in [N_2]} \left(\sum_{k_1 \in [N_1]} a_{k_1,k_0} \cdot \zeta^{N_2jk_1}\right) \cdot \zeta^{j_0k_0} \cdot \zeta^{N_1j_1k_0}\\ \end{aligned} Aj1,j0:=k0[N2]k1[N1]ak1,k0ζjk=k0[N2] k1[N1]ak1,k0ζN2jk1 ζjk0=k0[N2] k1[N1]ak1,k0ζN2jk1 ζj0k0ζN1j1k0
于是,将 a N a_N aN 按照行主序,排列为形状 N 1 × N 2 N_1 \times N_2 N1×N2 的矩阵 a N 1 × N 2 a_{N_1 \times N_2} aN1×N2

  1. 对于每一个 k 0 k_0 k0,利用形状 N 1 × N 1 N_1 \times N_1 N1×N1 的矩阵
    W 1 : = { ζ j 0 k 1 } j 0 , k 1 W_1:=\{\zeta^{j_0k_1}\}_{j_0,k_1} W1:={ζj0k1}j0,k1
    计算长度为 N 1 N_1 N1 的各个列矢 a k 0 a_{k_0} ak0NTT 变换(单位根为 { ζ N 1 j 0 , j 0 ∈ [ N 1 ] } \{\zeta_{N_1}^{j_0},j_0 \in [N_1]\} {ζN1j0,j0[N1]}),得到形状 N 1 × N 2 N_1 \times N_2 N1×N2 的矩阵
    W 1 × a N 1 × N 2 = { A j 0 , k 0 ′ : = ∑ k 1 ∈ [ N 1 ] a k 1 , k 0 ⋅ ζ N 2 j k 1 } j 0 , k 0 W_1 \times a_{N_1 \times N_2} = \left\{A_{j_0,k_0}' := \sum_{k_1 \in [N_1]} a_{k_1,k_0} \cdot \zeta^{N_2jk_1}\right\}_{j_0,k_0} W1×aN1×N2= Aj0,k0:=k1[N1]ak1,k0ζN2jk1 j0,k0

  2. 利用形状 N 1 × N 2 N_1 \times N_2 N1×N2 的矩阵
    W 2 : = { ζ j 0 k 0 } j 0 , k 0 W_2 := \{\zeta^{j_0k_0}\}_{j_0,k_0} W2:={ζj0k0}j0,k0
    对它做 Hadamard 乘积,扭曲矩阵 A ′ A' A 使得接下来的运算是标准 NTT(否则就需要恰当的扭曲后续 NTT 采用的单位根),此时的结果是形状 N 1 × N 2 N_1 \times N_2 N1×N2 的矩阵
    W 2 ⊙ A N 1 × N 2 ′ = { A j 0 , k 0 ′ ′ : = ζ j 0 k 0 ⋅ ∑ k 1 ∈ [ N 1 ] a k 1 , k 0 ⋅ ζ N 2 j k 1 } j 0 , k 0 W_2 \odot A_{N_1 \times N_2}' = \left\{A_{j_0,k_0}'' := \zeta^{j_0k_0} \cdot\sum_{k_1 \in [N_1]} a_{k_1,k_0} \cdot \zeta^{N_2jk_1}\right\}_{j_0,k_0} W2AN1×N2= Aj0,k0′′:=ζj0k0k1[N1]ak1,k0ζN2jk1 j0,k0

  3. 对于每一个 j 1 j_1 j1,利用形状 N 2 × N 2 N_2 \times N_2 N2×N2 的矩阵
    W 3 : = { ζ N 2 j 1 k 0 } j 1 , k 0 W_3 := \{\zeta_{N_2}^{j_1k_0}\}_{j_1,k_0} W3:={ζN2j1k0}j1,k0
    计算长度为 N 2 N_2 N2 的各个行矢 A j 0 ′ ′ A_{j_0}'' Aj0′′NTT 变换(单位根为 { ζ N 2 j 1 , j 1 ∈ [ N 2 ] } \{\zeta_{N_2}^{j_1},j_1 \in [N_2]\} {ζN2j1,j1[N2]}),得到形状 N 2 × N 1 N_2 \times N_1 N2×N1 的矩阵
    W 3 × ( A N 1 × N 2 ′ ′ ) T = { A j 1 , j 0 } j 1 , j 0 W_3 \times (A_{N_1 \times N_2}'')^T = \{A_{j_1,j_0}\}_{j_1,j_0} W3×(AN1×N2′′)T={Aj1,j0}j1,j0

对于形状 N 2 × N 1 N_2 \times N_1 N2×N1 的矩阵 A N 2 × N 1 A_{N_2 \times N_1} AN2×N1,按照行主序读取为 A N = N T T ( a N ) A_N = NTT(a_N) AN=NTT(aN)

总之, a N , A N a_N, A_N aN,AN 都按照行主序排列为矩阵(形状不同),那么有:
A N 2 × N 1 = W 3 × ( W 2 ⊙ ( W 1 × a N 1 × N 2 ) ) T A_{N_2 \times N_1} = W_3 \times \Big(W_2 \odot \big(W_1 \times a_{N_1 \times N_2}\big)\Big)^T AN2×N1=W3×(W2(W1×aN1×N2))T
其实,这个过程可以用 Nussbaumer Transform 的环同态表示
F [ x ] / ( x N − 1 ) ≅ ( F [ y ] / ( y N 1 − 1 ) ) [ x ] / ( x N 2 − y ) ≅ ( F [ y ] / ( y N 1 − 1 ) ) [ z ] / ( z N 2 − 1 ) \mathbb F[x]/(x^N-1) \cong \Big(\mathbb F[y]/(y^{N_1}-1)\Big)[x]/(x^{N_2}-y) \cong \Big(\mathbb F[y]/(y^{N_1}-1)\Big)[z]/(z^{N_2}-1) F[x]/(xN1)(F[y]/(yN11))[x]/(xN2y)(F[y]/(yN11))[z]/(zN21)

CHKKS18

[CHKKS18] 利用 SIMD 技术的 HadamardRotate 运算,实现同态的线性运算,它也采取了 BSGS 技巧。 我们默认 index 都是自动 ( m o d n ) \pmod n (modn) 的,基本符号:

  • 对于任意的线性变换 M ∈ C n × n M \in \mathbb C^{n \times n} MCn×n,简记 d i a g i ( M ) = [ M 0 , i , M 1 , i + 1 , ⋯ , M n , i + n ] diag_i(M) = [M_{0,i}, M_{1,i+1},\cdots,M_{n,i+n}] diagi(M)=[M0,i,M1,i+1,,Mn,i+n] 是第 i ∈ Z i \in \mathbb Z iZ 条对角线(可以是负数 − i -i i,就是第 n − i n-i ni 条对角线)
  • 对于任意的矢量 v ∈ C n v \in \mathbb C^{n} vCn,简记 r o t i ( v ) = [ v i , v i + 1 , ⋯ , v i + n − 1 ] rot_i(v) = [v_i,v_{i+1},\cdots,v_{i+n-1}] roti(v)=[vi,vi+1,,vi+n1] 是循环左移 i ∈ Z i \in \mathbb Z iZ 距离(可以是负数 − i -i i,循环右移 i i i 距离)

采取 BSGS 算法,分解 n = l × k n=l \times k n=l×k,线性变换可以表示为:

在这里插入图片描述

最优化时选取 k ≈ n k \approx \sqrt n kn ,计算复杂度为: O ( n ) O(\sqrt n) O(n ) 次 Rotate 运算(关于 v v v 的密文), O ( n ) O(n) O(n) 次 Hadamard 运算。对于公开的固定矩阵 M M M,其中的 r o t − k i ( d i a g k i + j ( M ) ) rot_{-ki}(diag_{ki+j}(M)) rotki(diagki+j(M)) 是预计算的常数多项式(用 InvDFT 编码),它不需要 CKKS 密文下的 Rotate 运算。

在这里插入图片描述

[CHKKS18] 将上述的线性变换转换到 slot-packing CKKS 下同态计算,并利用它来实现 coeff-to-slot,从而批处理 CKKS 自举。用到的线性变换是 DFT 和 InvDFT,[CHKKS18] 将它们视为通用的线性变换,利用这个同态矩阵乘法来实现。

不过,对于公开的线性变换,直接使用 TFHE 提出的那种 Functional Key-Switch,效率要高得多。对于秘密的线性变换,TFHE 也提出了根据 M M M 来构造 KS-Key for M,从而支持 Private Functional Key-Switch。但是如果没有提供这种特殊的 KS-Key for M,而是将 M M M 加密为一般的 CKKS 密文,那么就只能使用上面的同态矩阵乘法,利用 Rotate 和 Hadamard 慢慢计算。

Faster Homomorphic DFT

[CHH18] 观察到 DFT 矩阵拥有稀疏分解(也就是蝴蝶算法),因此对于这种特殊的线性变换,可以比 [CHKKS18] 的通用矩阵乘法,复杂度降低一个 n n n 因子。它可以应用在 [CHKKS18] 的 CKKS 批自举上,计算速度提高了数百倍。

Sparse-Diagonal matrix Factorization

[CHH18] 它说根据 [CT65] 的递归式 FFT,可以将 DFT 矩阵做如下的稀疏分解:

在这里插入图片描述

继续迭代地分解前者,最终可以获得:

在这里插入图片描述

容易看出, d i a g i ( D 2 i ( n ) ) ≠ 0 ⃗ ⟺ k ∈ { 0 , ± n 2 i } diag_i(D_{2^i}^{(n)}) \neq \vec 0 \iff k\in \{0,\pm \dfrac{n}{2^i}\} diagi(D2i(n))=0 k{0,±2in},只有 3 条对角线是非零的,因此采取斜线乘法来计算是十分高效的,
D 2 i ( n ) ⋅ v = ∑ k ∈ { 0 , ± n / 2 i } d i a g k ( D 2 i ( n ) ) ⊙ r o t k ( v ) D_{2^i}^{(n)} \cdot v = \sum_{k\in \{0,\pm n/2^i\}} diag_k(D_{2^i}^{(n)}) \odot rot_{k}(v) D2i(n)v=k{0,±n/2i}diagk(D2i(n))rotk(v)
算法为:

在这里插入图片描述

注意到 r o t 0 ( v ) = v rot_0(v)=v rot0(v)=v 不必计算,对于特殊情况 i = 1 i=1 i=1 根据 r o t n / 2 i ( v ) = r o t − n / 2 i ( v ) rot_{n/2^i}(v)=rot_{-n/2^i}(v) rotn/2i(v)=rotn/2i(v) 可节约计算。最终, D F T ⋅ v = ∏ i = 0 log ⁡ 2 n D 2 i ( n ) ⋅ v DFT \cdot v = \prod_{i=0}^{\log_2 n} D_{2^i}^{(n)} \cdot v DFTv=i=0log2nD2i(n)v 的复杂度为 O ( log ⁡ 2 n ) O(\log_2 n) O(log2n)

对于逆变换,由于 DFT 的逆矩阵恰好是其厄米,

在这里插入图片描述
因此很明显 CT 蝴蝶和上述的 GS 蝴蝶一样,也是稀疏对角的,从而也存在类似的快速矩阵乘法。

Radix-r

不过虽然上述的操作次数很小,但是计算深度为 log ⁡ 2 ( n ) \log_2(n) log2(n),需要多层 Rotate 和 CMult 串行,可能导致噪声控制的问题。我们可以合并某些连续的 k k k 个矩阵,那么深度就降低为 log ⁡ r n , r = 2 k \log_r n, r=2^k logrn,r=2k,代价是计算复杂度的上升。

在这里插入图片描述

根据对角阵的乘法性质:两个对角阵的乘积,依旧是对角阵,
d i a g i ( a ) ⋅ d i a g j ( b ) = d i a g i + j ( a ⊙ r o t i ( b ) ) diag_i(a) \cdot diag_j(b) = diag_{i+j}(a \odot rot_i(b)) diagi(a)diagj(b)=diagi+j(aroti(b))
可以证明,连续 k k k 个矩阵的合并
D k , s = D 2 s + k ( n ) ⋯ D 2 s + 2 ( n ) ⋅ D 2 s + 1 ( n ) D_{k,s} = D_{2^{s+k}}^{(n)} \cdots D_{2^{s+2}}^{(n)} \cdot D_{2^{s+1}}^{(n)} Dk,s=D2s+k(n)D2s+2(n)D2s+1(n)
的非零对角线的索引为
e 1 ⋅ n 2 s + 1 + e 2 ⋅ n 2 s + 2 + ⋯ + e t ⋅ n 2 s + k e_1 \cdot \dfrac{n}{2^{s+1}} + e_2 \cdot \dfrac{n}{2^{s+2}} + \cdots + e_t \cdot \dfrac{n}{2^{s+k}} e12s+1n+e22s+2n++et2s+kn
其中 e i ∈ { 0 , ± 1 } e_i \in \{0,\pm1\} ei{0,±1},易知这些 index 都是 n 2 s + k \dfrac{n}{2^{s+k}} 2s+kn 的倍数,绝对值上界为 ( 2 k − 1 ) n 2 s + k \dfrac{(2^k-1)n}{2^{s+k}} 2s+k(2k1)n,这些 index 的个数至多为 2 k + 1 − 1 2^{k+1}-1 2k+11

此时的 DFT 的复杂度为: O ( r log ⁡ r n ) O(r \log_r n) O(rlogrn) 次 Rotate 和 Hadamard,深度为 O ( log ⁡ r n ) O(\log_r n) O(logrn)

Hybrid method

由于上述分解的非零 index 呈现算术级数(都是 n 2 s + k \dfrac{n}{2^{s+k}} 2s+kn 的倍数),因此可以采取 BSGS 技巧,提取出公共的计算部分,进一步提高计算效率。

在这里插入图片描述

最优化设置 k 2 ≈ t k_2 \approx \sqrt t k2t ,此时 DFT 的复杂度为:依旧 O ( r log ⁡ r n ) O(r \log_r n) O(rlogrn) 次 Hadamard,但是只需 O ( r log ⁡ r n ) O(\sqrt r \log_r n) O(r logrn) 次 Ratate(但 r r r 是常数),深度也还是 O ( log ⁡ r n ) O(\log_r n) O(logrn)

Result

同态 DFT 的执行时间:秒的量级

在这里插入图片描述

CKKS 自举时间:2 分钟延迟,均摊 4 毫秒

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/228639.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构 —— 二叉树的链式结构实现】

数据结构 —— 二叉树的链式结构实现 1.树的概念及其结构1.1.树概念1.2.树的结构1.3树的相关概念1.4.树的表示1.5. 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树的概念及其结构2.1二叉树的概念2.2.现实中的二叉树&#xff1a;2.3. 特殊的二叉树…

国产操作系统-银河麒麟V10

一、介绍 银河麒麟操作系统隶属于麒麟软件&#xff0c;麒麟软件是专业从事国产操作系统研发和产业化的企业&#xff0c;面向通用和专用领域打造安全创新的国产操作系统产品和相应解决方案&#xff0c;旗下拥有银河麒麟、中标麒麟、星光麒麟三大产品品牌。 麒麟软件官方网站地…

Shell条件变量练习

1.算数运算命令有哪几种&#xff1f; (1) "(( ))"用于整数运算的常用运算符&#xff0c;效率很高 [rootshell scripts]# echo $((24*5**2/8)) #(( ))2452814 14 (2) "$[ ] "用于整数运算 [rootshell scripts]# echo $[24*5**2/8] #[ ]也可以运…

Windows10系统卸载服务和删除服务

记录一下Windows10系统卸载服务和删除服务 最近在使用自己win电脑的时候 发现服务里存在很久之前就没有使用的应用&#xff0c;对应的文件夹也都已经删除了&#xff0c;但是在win服务里一直存在&#xff0c;不知道会不会影响性能&#xff0c;看着吧还是强迫自己删掉好一些&…

解决:SyntaxError: Non-UTF-8 code starting with À in file but no encoding declared

解决&#xff1a;SyntaxError: Non-UTF-8 code starting with in file but no encoding declared 文章目录 解决&#xff1a;SyntaxError: Non-UTF-8 code starting with in file but no encoding declared背景报错问题报错翻译报错原因解决方法使用utf-8格式使用gbk格式今天…

Linux新加磁盘的完整步骤

目录 新加磁盘的完整步骤磁盘分区磁盘文件命名经典分区方案fdiskparted 分区格式化挂载分区 新加磁盘的完整步骤 物理连接 --> 分区 --> 格式化 --> 挂载 --> 更新/etc/fstab文件实现永久挂载 磁盘分区 主分区primary用来安装操作系统、存放数据&#xff0c;可以…

【攻防世界-misc】hong

1.下载解压文件&#xff0c;是个音频文件&#xff0c;但打不开 2.复制到kali中先拆分看音频里面有隐含文件没有 用到的命令是&#xff1a;foremost 桌面/hong.mp3 点击桌面上的主文件夹 点击“output”文件夹&#xff0c; 点击文件中的jpg文件夹&#xff0c;有两张图片&#…

【古月居《ros入门21讲》学习笔记】14_参数的使用与编程方法

目录 说明&#xff1a; 1. 参数模型&#xff08;全局字典&#xff09; 2. 实现过程&#xff08;C&#xff09; 创建功能包 参数命令行的使用 YAML参数文件 rosparam命令 使用示例 编程方法&#xff08;C&#xff09; 配置代码编译规则 编译并运行 编译 运行 3. 实…

uni-app x生成的安卓包,安装时,提示不兼容。解决方案

找到 manifest.json 进入&#xff1a;源码视图 代码 {"name" : "xxx康养","appid" : "__xxx6","description" : "xxx康养","versionName" : "1.0.12","versionCode" : 100012,&…

【CAD二次开发】标注箭头,获取修改标注箭头图块

常见的的标注箭头有以下种类 public static List<string> ArrowBlock = new List<string>(){" ","_CLOSEDBLANK&

ABAP算法 模拟退火

模拟退火算法 算法原理及概念本文仅结合实现过程做简述 模拟退火算法是一种解决优化问题的算法。通过模拟固体退火过程中的原子热运动来寻找全局最优解。在求解复杂问题时&#xff0c;模拟退火算法可以跳出局部最优解获取全局最优解。 模拟退火算法包含退火过程和Metropolis算法…

socket 一个完整的不错的示例

从客户端向服务器端发送信息时&#xff0c;在服务器端有打印显示&#xff1b; 检测环境常用&#xff0c;备份一下 0&#xff0c;公共头文件代码 //config.h#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #inc…