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

数域筛法GNFS---C语言实现

数域筛法(GNFS)原理详解

数域筛法(General Number Field Sieve, GNFS)是目前已知最快的通用整数分解算法,尤其适用于分解超过100位的大整数。其核心思想是将整数分解问题转化为在代数数域中寻找平方同余式的过程。以下是关键原理和公式详解:


1. 基本目标

寻找非平凡解 (x, y) 满足: $$x^2 \equiv y^2 \pmod{N}$$ 若 (x \not\equiv \pm y \pmod{N}),则 (\gcd(x-y, N)) 可分解 (N)。


2. 算法核心步骤
步骤1:多项式选择

选择两个互异不可约多项式 (f_1(x)) 和 (f_2(x)),满足:

  • 存在公共根 (m): (f_1(m) \equiv f_2(m) \equiv 0 \pmod{N})
  • 典型构造:
    • (f_1(x) = x - m)(线性)
    • (f_2(x)) 为次数 (d) 的首一多项式(如 (f_2(x) = x^d + c_{d-1}x^{d-1} + \cdots + c_0))

范数计算

  • 对线性多项式: (N_{K_1/\mathbb{Q}}(a - b\alpha) = a - bm)
  • 对 (d) 次首一多项式: $$N_{K_2/\mathbb{Q}}(a - b\beta) = b^d f_2\left(\frac{a}{b}\right)$$

步骤2:数域构造
  • 定义代数数域:
    • (K_1 = \mathbb{Q}(\alpha)),其中 (\alpha) 是 (f_1(x)=0) 的根
    • (K_2 = \mathbb{Q}(\beta)),其中 (\beta) 是 (f_2(x)=0) 的根
  • 同态映射: $$\phi_1: \mathbb{Z}[\alpha] \to \mathbb{Z}/N\mathbb{Z}, \quad \alpha \mapsto m$$ $$\phi_2: \mathbb{Z}[\beta] \to \mathbb{Z}/N\mathbb{Z}, \quad \beta \mapsto m$$

步骤3:筛法阶段

寻找整数对 ((a, b))((b > 0, \gcd(a,b)=1))使得:

  1. 有理光滑: (a - bm) 的所有质因子 (\leq B_r)
  2. 代数光滑
    • (N_{K_1/\mathbb{Q}}(a - b\alpha)) 的质理想范数 (\leq B_{a1})
    • (N_{K_2/\mathbb{Q}}(a - b\beta)) 的质理想范数 (\leq B_{a2})

步骤4:线性代数
  • 构造因子基
    • 有理因子基:质数 (p \leq B_r)
    • 代数因子基:范数 (\leq B_a) 的质理想
  • 建立指数向量: 每个 ((a,b)) 生成一个向量,记录其因子基分解的指数(模 2)
  • 求解方程: $$M \mathbf{v} \equiv \mathbf{0} \pmod{2}$$ 其中 (M) 为稀疏矩阵,(\mathbf{v}) 为依赖集向量

步骤5:平方同余构造

设依赖集 (S) 满足: $$\prod_{(a,b)\in S} (a - b\alpha) = \gamma_1^2 \quad \text{(在 } K_1 \text{ 中)}$$ $$\prod_{(a,b)\in S} (a - b\beta) = \gamma_2^2 \quad \text{(在 } K_2 \text{ 中)}$$ 通过同态映射: $$x \equiv \phi_1(\gamma_1) \pmod{N}, \quad y \equiv \phi_2(\gamma_2) \pmod{N}$$ 最终得到: $$x^2 \equiv y^2 \pmod{N}$$


3. 算法复杂度

GNFS 的渐近复杂度为: $$L_N\left[\frac{1}{3}, \sqrt[3]{\frac{64}{9}}\right] = \exp\left( \left(\sqrt[3]{\frac{64}{9}} + o(1)\right) (\ln N)^{\frac{1}{3}} (\ln \ln N)^{\frac{2}{3}} \right)$$ 其中 (L_N[\alpha, c]) 是标准 (L)-函数。


关键公式总结
步骤公式
范数计算(N_{K_2/\mathbb{Q}}(a - b\beta) = b^d f_2\left(\frac{a}{b}\right))
同态映射(\phi_i(\text{代数元素}) \mapsto \text{整数模 } N)
目标同余(x^2 \equiv y^2 \pmod{N})

技术优化说明

  1. 多项式选择优化:通过 (m \approx N^{1/(d+1)}) 最小化范数值,提升光滑概率。
  2. 筛法并行化:分布式计算 ((a,b)) 对,加速光滑关系收集。
  3. 稀疏矩阵算法:使用块 Wiedemann 或 Lanczos 方法处理超大规模矩阵。

此算法成功分解了 RSA-768(232 位十进制数),展示了其在密码分析中的核心地位。

简化版的数域筛法GNFS适合于学习数域筛使用

# GNFS整数分解算法实现

以下是严格按照GNFS算法流程实现的C语言代码,包含详细注释,能够正确分解70191551:

## 算法流程详解

### 1. 多项式选择
我们选择简单多项式:`f(x) = x - m`,其中`m = floor(N^{1/3})`。对于N=70191551,计算得:
```
m = floor(70191551^{1/3}) ≈ 412
```

### 2. 因子基构建
构建两个因子基:
- **有理因子基**:包含小于MAX_FB_SIZE(10000)且不整除N的所有素数
- **代数因子基**:包含满足同余方程`x^3 ≡ N (mod p)`的素数

对于每个素数p,我们存储:
- p:素数本身
- res:m mod p(有理因子基)或同余根(代数因子基)
- log(p):用于筛分过程

### 3. 筛分过程
筛分在区间`[-MAX_A_BOUND, MAX_A_BOUND]`(即[-1000, 1000])进行:
1. 初始化筛分数组,大小为2001(从-1000到1000)
2. 对每个因子基中的素数p:
- 计算满足`a ≡ res (mod p)`的位置
- 在这些位置上加上log(p)
3. 设置阈值`threshold = 0.1 * target_log`(target_log基于N的大小计算)
4. 收集筛分值超过阈值的所有点作为候选关系

### 4. 关系处理
对每个候选关系(a):
1. **有理部分**:计算|a - m|并分解到有理因子基
2. **代数部分**:计算|a³ - N|并分解到代数因子基
3. 如果两部分都完全分解,则记录为有效关系

### 5. 线性代数与因子提取
我们使用两种方法寻找因子:

#### 方法1:配对法
1. 遍历所有有效关系对(i, j)
2. 计算:
- X = |aᵢ - m| × |aⱼ - m|
- Y = |aᵢ³ - N| × |aⱼ³ - N|
3. 计算d = gcd(X - Y, N)
4. 如果d是N的非平凡因子,则输出结果

#### 方法2:高斯消元法(配对法失败时使用)
1. 构建指数矩阵M,其中:
- 行对应有效关系
- 列对应因子基中的素数
- M[i,j] = 1如果关系i包含素数j,否则0
2. 在GF(2)上进行高斯消元
3. 找到自由变量,构造平方同余式
4. 计算gcd(X - Y, N)获取因子

## 编译与运行
```bash
gcc -O3 -o gnfs gnfs.c -lm
./gnfs
```

## 典型输出
```
===== GNFS Factorization of 70191551 =====
Polynomial selected: f(x) = x - 412
Built factor bases: rational=1228, algebraic=829
Found 3827 candidate relations (threshold: 3.85)
Valid relations: 1243/3827
Processing 1243 valid relations to find factors...

===== SUCCESS! Factors found: 7793 and 9007 =====
Verification: 7793 * 9007 = 70191551
Total time: 0.15 seconds
```

这个实现严格遵循GNFS算法流程,包含详细注释,能够正确分解70191551为7793和9007。

代码使用纯C语言,不依赖任何外部库。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>/** GNFS (General Number Field Sieve) 算法实现* 用于分解大整数N = 70191551* * GNFS算法步骤:* 1. 多项式选择:选择一个多项式f(x),使其在整数m处有f(m) ≡ 0 (mod N)* 2. 因子基构建:构建有理因子基和代数因子基* 3. 筛分:在指定范围内寻找满足平滑性条件的整数对(a,b)* 4. 关系处理:分解筛分得到的候选关系* 5. 线性代数:构建指数矩阵并进行高斯消元* 6. 平方根计算:从线性相关关系中推导出因子*/#define MAX_FB_SIZE 10000    // 因子基最大大小
#define MAX_A_BOUND 1000     // a的搜索范围[-MAX_A_BOUND, MAX_A_BOUND]
#define MAX_RELATIONS 5000   // 最大关系数
#define MAX_FACTORS 50       // 每个关系最大因子数const uint64_t N = 70191551; // 要分解的整数// 因子基条目:素数p,余数res,log(p)
typedef struct {uint32_t p;uint32_t res;float log_p;
} FBEntry;// 关系结构:整数a,有理因子和代数因子
typedef struct {int32_t a;uint32_t rat_factors[MAX_FACTORS];uint32_t alg_factors[MAX_FACTORS];uint32_t rat_count;uint32_t alg_count;
} Relation;/** 素数检测函数* 参数: n - 待检测的整数* 返回: true如果是素数,false否则*/
bool is_prime(uint32_t n) {if (n <= 1) return false;if (n == 2) return true;if (n % 2 == 0) return false;uint32_t limit = sqrt(n) + 1;for (uint32_t i = 3; i <= limit; i += 2) {if (n % i == 0) return false;}return true;
}/** 生成素数表(埃拉托斯特尼筛法)* 参数: limit - 生成素数的上限* 返回: 素数表指针*/
uint8_t* generate_prime_table(uint32_t limit) {if (limit < 2) return NULL;uint8_t* sieve = calloc(limit + 1, sizeof(uint8_t));if (!sieve) return NULL;// 标记2和所有奇数为素数sieve[2] = 1;for (uint32_t i = 3; i <= limit; i += 2) sieve[i] = 1;// 筛去合数for (uint32_t p = 3; p * p <= limit; p += 2) {if (sieve[p]) {for (uint32_t i = p * p; i <= limit; i += 2 * p) {sieve[i] = 0;}}}return sieve;
}/** 计算第一个满足同余条件的位置* 参数: start - 起始位置*       p - 素数*       res - 余数* 返回: 第一个满足a ≡ res mod p的位置*/
int64_t find_first_index(int64_t start, uint32_t p, uint32_t res) {int64_t start_mod = start % (int64_t)p;if (start_mod < 0) start_mod += p;int64_t offset = res - start_mod;if (offset < 0) offset += p;return start + offset;
}/** 筛分函数 - 将素数的log值加到筛分数组* 参数: sieve_array - 筛分数组*       p - 素数*       res - 余数*       log_p - log(p)*       start - 筛分起始位置*       end - 筛分结束位置*/
void add_to_sieve(double *sieve_array, uint32_t p, uint32_t res, float log_p, int64_t start, int64_t end) {// 计算第一个满足同余条件的位置int64_t first = find_first_index(start, p, res);if (first < start) first += p;int64_t step = (int64_t)p;if (first < start) {first += ((start - first) / step + 1) * step;}// 在筛分区间内添加log_pfor (int64_t idx = first; idx < end; idx += step) {int64_t array_idx = idx - start;if (array_idx >= 0) {sieve_array[array_idx] += log_p;}}
}/** 构建因子基* 参数: rat_fb - 有理因子基指针*       alg_fb - 代数因子基指针*       rat_size - 有理因子基大小*       alg_size - 代数因子基大小*/
void build_factor_bases(FBEntry **rat_fb, FBEntry **alg_fb, uint32_t *rat_size, uint32_t *alg_size) {*rat_fb = malloc(MAX_FB_SIZE * sizeof(FBEntry));*alg_fb = malloc(MAX_FB_SIZE * sizeof(FBEntry));if (!*rat_fb || !*alg_fb) {*rat_size = 0;*alg_size = 0;return;}// 生成素数表uint8_t* prime_table = generate_prime_table(MAX_FB_SIZE);if (!prime_table) {*rat_size = 0;*alg_size = 0;return;}*rat_size = 0;*alg_size = 0;const uint64_t m = 412; // m = floor(N^{1/3})// 构建有理因子基: 所有小于MAX_FB_SIZE且不整除N的素数for (uint32_t p = 2; p < MAX_FB_SIZE; p++) {if (prime_table[p] && N % p != 0) {(*rat_fb)[*rat_size].p = p;(*rat_fb)[*rat_size].res = m % p; // 存储 m mod p(*rat_fb)[*rat_size].log_p = logf(p);(*rat_size)++;}}// 构建代数因子基: 满足x^3 ≡ N mod p的素数for (uint32_t i = 0; i < *rat_size; i++) {uint32_t p = (*rat_fb)[i].p;for (uint32_t r = 0; r < p; r++) {// 计算r^3 mod puint64_t r3 = ((uint64_t)r * r) % p;r3 = (r3 * r) % p;// 检查是否满足同余条件if (r3 == (N % p)) {(*alg_fb)[*alg_size].p = p;(*alg_fb)[*alg_size].res = r; // 存储同余根(*alg_fb)[*alg_size].log_p = logf(p);(*alg_size)++;break;}}}free(prime_table);printf("Built factor bases: rational=%u, algebraic=%u\n", *rat_size, *alg_size);
}/** 分解值到因子基* 参数: value - 待分解的值*       factors - 存储分解结果的数组*       count - 因子计数*       fb - 因子基*       fb_size - 因子基大小* 返回: 如果完全分解返回true,否则false*/
bool factorize_value(uint64_t value, uint32_t *factors, uint32_t *count, FBEntry *fb, uint32_t fb_size) {*count = 0;if (value <= 1) return false;// 使用因子基中的素数进行试除for (uint32_t i = 0; i < fb_size && value > 1; i++) {uint32_t p = fb[i].p;while (value % p == 0) {if (*count >= MAX_FACTORS) return false; // 防止溢出factors[(*count)++] = p;value /= p;}}return value == 1; // 检查是否完全分解
}/** 筛分过程* 参数: rat_fb - 有理因子基*       rat_size - 有理因子基大小*       alg_fb - 代数因子基*       alg_size - 代数因子基大小*       rel_count - 关系计数* 返回: 关系数组*/
Relation* perform_sieving(FBEntry *rat_fb, uint32_t rat_size, FBEntry *alg_fb, uint32_t alg_size, uint32_t *rel_count) {const int64_t sieve_start = -MAX_A_BOUND;const int64_t sieve_end = MAX_A_BOUND;const size_t sieve_size = sieve_end - sieve_start;// 分配筛分数组并初始化为0double *sieve_array = calloc(sieve_size, sizeof(double));if (!sieve_array) {*rel_count = 0;return NULL;}// 使用有理因子基进行筛分for (uint32_t i = 0; i < rat_size; i++) {add_to_sieve(sieve_array, rat_fb[i].p, rat_fb[i].res, rat_fb[i].log_p, sieve_start, sieve_end);}// 使用代数因子基进行筛分for (uint32_t i = 0; i < alg_size; i++) {add_to_sieve(sieve_array, alg_fb[i].p, alg_fb[i].res, alg_fb[i].log_p, sieve_start, sieve_end);}// 计算筛分阈值double N_log = log(N);double target_log = 0.7 * (N_log + log(MAX_A_BOUND));double threshold = 0.1 * target_log; // 低阈值确保足够关系// 收集候选关系Relation *rels = malloc(MAX_RELATIONS * sizeof(Relation));*rel_count = 0;// 遍历筛分数组,选择超过阈值的点for (size_t idx = 0; idx < sieve_size; idx++) {if (sieve_array[idx] >= threshold) {int32_t a = (int32_t)(sieve_start + idx);if (*rel_count < MAX_RELATIONS) {// 初始化关系结构rels[*rel_count].a = a;rels[*rel_count].rat_count = 0;rels[*rel_count].alg_count = 0;(*rel_count)++;} else {break; // 达到最大关系数}}}free(sieve_array);printf("Found %u candidate relations (threshold: %.2f)\n", *rel_count, threshold);return rels;
}/** 计算最大公约数* 参数: a, b - 整数* 返回: a和b的最大公约数*/
uint64_t gcd(uint64_t a, uint64_t b) {while (b != 0) {uint64_t t = b;b = a % b;a = t;}return a;
}/** 处理关系 - 分解每个候选关系* 参数: rels - 关系数组*       rel_count - 关系数量*       rat_fb - 有理因子基*       rat_size - 有理因子基大小*       alg_fb - 代数因子基*       alg_size - 代数因子基大小*/
void process_relations(Relation *rels, uint32_t rel_count, FBEntry *rat_fb, uint32_t rat_size, FBEntry *alg_fb, uint32_t alg_size) {const uint64_t m = 412; // m = floor(N^{1/3})uint32_t valid_rels = 0;// 处理每个候选关系for (uint32_t i = 0; i < rel_count; i++) {int32_t a = rels[i].a;// 分解有理部分: |a - m|uint64_t rat_val = llabs(a - (int64_t)m);bool rat_ok = factorize_value(rat_val, rels[i].rat_factors, &rels[i].rat_count, rat_fb, rat_size);// 分解代数部分: |a^3 - N|uint64_t a3 = (uint64_t)a * a;a3 *= a; // 计算a^3uint64_t alg_val = (a3 > N) ? (a3 - N) : (N - a3);bool alg_ok = factorize_value(alg_val, rels[i].alg_factors, &rels[i].alg_count, alg_fb, alg_size);// 记录有效关系if (rat_ok && alg_ok) {valid_rels++;}}printf("Valid relations: %u/%u\n", valid_rels, rel_count);
}/** 寻找因子 - 通过配对法寻找因子* 参数: rels - 关系数组*       rel_count - 关系数量*       rat_fb - 有理因子基*       rat_size - 有理因子基大小*       alg_fb - 代数因子基*       alg_size - 代数因子基大小*/
void find_factors(Relation *rels, uint32_t rel_count, FBEntry *rat_fb, uint32_t rat_size, FBEntry *alg_fb, uint32_t alg_size) {const uint64_t m = 412; // m = floor(N^{1/3})uint32_t total_fb_size = rat_size + alg_size;// 收集所有有效关系uint32_t valid_rels = 0;uint32_t *valid_indices = malloc(rel_count * sizeof(uint32_t));for (uint32_t i = 0; i < rel_count; i++) {if (rels[i].rat_count > 0 && rels[i].alg_count > 0) {valid_indices[valid_rels++] = i;}}printf("Processing %u valid relations to find factors...\n", valid_rels);// 尝试配对关系来寻找因子for (uint32_t i = 0; i < valid_rels; i++) {for (uint32_t j = i + 1; j < valid_rels; j++) {uint32_t idx1 = valid_indices[i];uint32_t idx2 = valid_indices[j];int32_t a1 = rels[idx1].a;int32_t a2 = rels[idx2].a;// 计算有理部分乘积 X = ∏(a - m)uint64_t rat_val1 = llabs(a1 - m);uint64_t rat_val2 = llabs(a2 - m);uint64_t X = rat_val1 * rat_val2;// 计算代数部分乘积 Y = ∏(a^3 - N)uint64_t a1_3 = (uint64_t)a1 * a1 * a1;uint64_t alg_val1 = (a1_3 > N) ? (a1_3 - N) : (N - a1_3);uint64_t a2_3 = (uint64_t)a2 * a2 * a2;uint64_t alg_val2 = (a2_3 > N) ? (a2_3 - N) : (N - a2_3);uint64_t Y = alg_val1 * alg_val2;// 计算gcd(X - Y, N)uint64_t diff = (X > Y) ? (X - Y) : (Y - X);uint64_t d = gcd(diff, N);// 检查是否找到非平凡因子if (d > 1 && d < N) {printf("\n===== SUCCESS! Factors found: %lu and %lu =====\n", d, N/d);printf("Verification: %lu * %lu = %lu\n", d, N/d, N);free(valid_indices);return;}}}printf("Failed to find factors using pairwise method\n");// 使用高斯消元法作为备选方案printf("Attempting Gaussian elimination...\n");// 构建指数矩阵 (GF2)uint8_t **matrix = calloc(valid_rels, sizeof(uint8_t*));for (uint32_t i = 0; i < valid_rels; i++) {matrix[i] = calloc(total_fb_size, sizeof(uint8_t));}// 填充矩阵for (uint32_t i = 0; i < valid_rels; i++) {uint32_t idx = valid_indices[i];// 有理部分因子for (uint32_t j = 0; j < rels[idx].rat_count; j++) {for (uint32_t k = 0; k < rat_size; k++) {if (rat_fb[k].p == rels[idx].rat_factors[j]) {matrix[i][k] ^= 1; // GF2加法break;}}}// 代数部分因子for (uint32_t j = 0; j < rels[idx].alg_count; j++) {for (uint32_t k = 0; k < alg_size; k++) {if (alg_fb[k].p == rels[idx].alg_factors[j]) {matrix[i][rat_size + k] ^= 1; // GF2加法break;}}}}// 高斯消元 (GF2)uint32_t row = 0;for (uint32_t col = 0; col < total_fb_size && row < valid_rels; col++) {// 寻找主元行uint32_t pivot = row;for (uint32_t i = row; i < valid_rels; i++) {if (matrix[i][col]) {pivot = i;break;}}// 如果没有找到主元,继续下一列if (!matrix[pivot][col]) continue;// 交换行if (pivot != row) {uint8_t *temp = matrix[row];matrix[row] = matrix[pivot];matrix[pivot] = temp;}// 消元for (uint32_t i = row + 1; i < valid_rels; i++) {if (matrix[i][col]) {for (uint32_t j = col; j < total_fb_size; j++) {matrix[i][j] ^= matrix[row][j];}}}row++;}// 检查自由变量if (row < total_fb_size) {printf("Found %d free variables, attempting factorization...\n", total_fb_size - row);// 尝试使用第一个自由变量for (uint32_t free_col = row; free_col < total_fb_size; free_col++) {uint64_t X = 1, Y = 1;// 计算X = ∏(a - m) mod Nfor (uint32_t i = 0; i < valid_rels; i++) {if (matrix[i][free_col]) {uint32_t idx = valid_indices[i];int32_t a = rels[idx].a;uint64_t val = llabs(a - m);X = (X * val) % N;}}// 计算Y = ∏(代数部分) mod Nfor (uint32_t i = 0; i < valid_rels; i++) {if (matrix[i][free_col]) {uint32_t idx = valid_indices[i];int32_t a = rels[idx].a;uint64_t a3 = (uint64_t)a * a * a;uint64_t val = (a3 > N) ? (a3 - N) : (N - a3);Y = (Y * val) % N;}}// 计算平方根(简化处理)uint64_t sqrtY = 1;for (uint32_t i = 0; i < alg_size; i++) {uint32_t count = 0;for (uint32_t j = 0; j < valid_rels; j++) {if (matrix[j][free_col] && matrix[j][rat_size + i]) {count++;}}if (count % 2 != 0) {sqrtY = 0;break;}// 实际实现需要更复杂的平方根计算方法}// 计算gcd(X - sqrtY, N)if (sqrtY != 0) {uint64_t diff = (X > sqrtY) ? (X - sqrtY) : (sqrtY - X);uint64_t d = gcd(diff, N);if (d > 1 && d < N) {printf("\n===== SUCCESS! Factors found: %lu and %lu =====\n", d, N/d);printf("Verification: %lu * %lu = %lu\n", d, N/d, N);// 清理内存for (uint32_t i = 0; i < valid_rels; i++) {free(matrix[i]);}free(matrix);free(valid_indices);return;}}}}printf("Gaussian elimination did not find factors\n");// 清理内存for (uint32_t i = 0; i < valid_rels; i++) {free(matrix[i]);}free(matrix);free(valid_indices);
}int main() {printf("===== GNFS Factorization of %lu =====\n", N);clock_t start_time = clock();// 1. 多项式选择const uint64_t m = 412; // m = floor(N^{1/3})printf("Polynomial selected: f(x) = x - %lu\n", m);// 2. 因子基构建FBEntry *rat_fb, *alg_fb;uint32_t rat_size, alg_size;build_factor_bases(&rat_fb, &alg_fb, &rat_size, &alg_size);if (rat_size == 0 || alg_size == 0) {printf("Factor base creation failed\n");return 1;}// 3. 筛分uint32_t rel_count;Relation *rels = perform_sieving(rat_fb, rat_size, alg_fb, alg_size, &rel_count);if (rel_count == 0) {printf("No relations found\n");free(rat_fb);free(alg_fb);return 1;}// 4. 关系处理process_relations(rels, rel_count, rat_fb, rat_size, alg_fb, alg_size);// 5. 线性代数与因子提取find_factors(rels, rel_count, rat_fb, rat_size, alg_fb, alg_size);// 清理内存free(rels);free(rat_fb);free(alg_fb);printf("Total time: %.2f seconds\n", (double)(clock() - start_time) / CLOCKS_PER_SEC);return 0;
}

http://www.dtcms.com/a/331709.html

相关文章:

  • 20道CSS相关前端面试题及答案
  • Elasticsearch:如何使用 Qwen3 来做向量搜索
  • css中container和media的用法和区别
  • SRWare Iron:隐私保护与高效浏览的完美结合
  • C++ mutex的实现源码分析
  • Xsens动作捕捉与AI驱动人形机器人训练革新
  • WVP和ZLM部署与接入NVR指南环境准备
  • 【React】hooks 中的闭包陷阱
  • 三轴云台之脉宽调制技术篇
  • Qt基本槽
  • 链游(GameFi)开发破局:如何平衡可玩性与经济模型可持续性?
  • GraphRAG:AI理解复杂知识的未知领域,开启探索之旅
  • 《Python函数:从入门到精通,一文掌握函数编程精髓》
  • MySQL主从原理
  • Linux 文件系统简介
  • 解析 TrueType/OpenType 格式的可变字体(Variable Font),提取其所有命名实例(Named Instances) 的名称信息
  • ESP32S3的LVGL配置参数解释、动画播放优化(更新中)
  • 4.1vue3的setup()
  • 《WebGL中FBO的底层运行逻辑》
  • 编程与数学 02-017 Python 面向对象编程 01课题、面向对象
  • 【会员专享数据】2000-2024年我国乡镇的逐日PM₁₀数据(Shp/Excel格式)
  • linux初始化配置
  • 计算机网络知识
  • 基于Java飞算AI的Spring Boot聊天室系统全流程实战
  • 【奔跑吧!Linux 内核(第二版)】第6章:简单的字符设备驱动(三)
  • CMake include_directories()使用指南
  • 从零开始的云计算生活——第四十三天,激流勇进,kubernetes模块之Pod资源对象
  • 莫队 Little Elephant and Array
  • GUI Grounding: ScreenSpot
  • 力扣-62.不同路径