Luke a Pro

Luke Sun

Developer & Marketer

🇺🇦
EN||

同余运算 (Modular Arithmetic)

| , 4 minutes reading.

同余运算:数字时钟

算法背后的故事:循环的逻辑

想象你有一个时钟。如果现在是 10 点,你等待了 4 个小时,现在是几点? 在普通数学中,10+4=1410 + 4 = 14。但在时钟上,它是 22 点。

这就是 同余运算 (Modular Arithmetic),也被称为“时钟算术”。数字 12 就是这里的 模 (Modulus)。每当你达到 12,你就会重置并重新开始。

这个系统的天才之处在于,它允许我们用有限的空间处理无限的序列。无论一个数字变得多大,如果你对它取模 mod 100,它永远会落在 0 到 99 之间。这就是“在边界内行事”的艺术。

为什么需要它?

  • 哈希: 为了将巨大的用户 ID 映射到小型数组的索引中,我们使用 hash(ID) % array_size
  • 密码学: 公钥加密(如 RSA)完全建立在模幂运算之上。它就像一条单行道:计算“时钟上的时间”很容易,但仅通过观察指针来推算“过去了多少天”几乎是不可能的。
  • Diffie-Hellman 密钥交换: 允许两个人在公开渠道上通过在“模数时钟”上“混合颜色”来达成秘密密钥。
  • 游戏逻辑: 让角色在屏幕边缘循环出现:x = (x + speed) % screen_width

算法是如何“思考”的

同余运算遵循它自己的平衡法则:

  1. 加法: (A+B)(modM)=(A(modM)+B(modM))(modM)(A + B) \pmod M = (A \pmod M + B \pmod M) \pmod M
  2. 乘法: (AimesB)(modM)=(A(modM)imesB(modM))(modM)(A imes B) \pmod M = (A \pmod M imes B \pmod M) \pmod M
  3. 模逆元: 这是最难的部分。在模运算中,除以 XX 等同于乘以“XX 的逆元”。这是破解(或制造)密码的核心。

工程决策:溢出保护

在编程中,我们经常需要计算巨大的和或积。

  • 如果你先计算 (AimesBimesC)(A imes B imes C) 再取模,中间结果可能会大到溢出 64 位整数,导致得到垃圾数据。
  • 专家提示: 在每一步都应用模运算。(AimesB(modM))imesC(modM)(A imes B \pmod M) imes C \pmod M。这能保持数值小巧且安全。

实现参考 (Python)

def modular_exponentiation(base, exp, mod):
    # 高效计算 (base^exp) % mod
    # 时间复杂度 O(log exp) —— 这是密码学的核心
    res = 1
    base = base % mod
    while exp > 0:
        if exp % 2 == 1:
            res = (res * base) % mod
        base = (base * base) % mod
        exp //= 2
    return res

# 示例
# 计算 (5^117) % 19
# 普通计算器会因为数字太大而失效,但同余运算能轻松处理
print(f"5^117 mod 19 的结果: {modular_exponentiation(5, 117, 19)}")
# Python 内置的 pow(base, exp, mod) 也经过了这种优化
print(f"原生 pow 结果: {pow(5, 117, 19)}")

小结

同余运算教会我们:限制创造了结构。通过创造一个数字周而复始的循环世界,我们可以用有限管理无限。它提醒我们,在工程实践中,有时候处理增长最强大的方法,就是明确在哪里重置。