洛谷 B4500 / B4449 / B3843 凯撒密码、密码强度与密码合规——加密与安全的三道门

洛谷 B4500 / B4449 / B3843 凯撒密码、密码强度与密码合规------加密与安全的三道门

📌 摘要

B4500 破解凯撒密码(从已知明密文对推断偏移量),B4449 检测密码强度(长度+大写+数字),B3843 验证密码合规(字符集+长度+组合规则)。三道题覆盖了用户系统安全的基础三道门:加密强度策略合规校验。本文从伪代码题解出发,延伸到密码学 2000 年进化史(凯撒→Enigma→RSA→AES)、密码存储安全(为什么不能存明文→哈希→加盐→Argon2)、以及 NIST 2025 密码新规(取消复杂度规则、推荐 15 字符密码、泄露密码筛查)------从洛谷入门题到每家公司的用户注册系统。

题目链接B4500 凯撒密码 | B4449 密码强度 | B3843 密码合规

📚 目录

  • [📝 前言](#📝 前言)

  • [🔍 三道题在考什么](#🔍 三道题在考什么)

  • [🏛️ B4500:凯撒密码](#🏛️ B4500:凯撒密码)

    • [💡 思路](#💡 思路)

    • [📝 伪代码](#📝 伪代码)

    • [🎯 关键点](#🎯 关键点)

  • [💪 B4449:密码强度](#💪 B4449:密码强度)

    • [💡 思路](#💡 思路)

    • [📝 伪代码](#📝 伪代码)

    • [🎯 关键点](#🎯 关键点)

  • [✅ B3843:密码合规](#✅ B3843:密码合规)

    • [💡 思路](#💡 思路)

    • [📝 伪代码](#📝 伪代码)

    • [🎯 关键点](#🎯 关键点)

  • [⚖️ 三道门的对比](#⚖️ 三道门的对比)

  • [⚠️ 注意事项](#⚠️ 注意事项)

  • [🌳 延伸:从凯撒密码到现代密码学](#🌳 延伸:从凯撒密码到现代密码学)

    • [📜 密码学 2000 年进化史](#📜 密码学 2000 年进化史)

    • [🔒 密码存储:为什么不能存明文](#🔒 密码存储:为什么不能存明文)

    • [📋 NIST 2025 密码新规](#📋 NIST 2025 密码新规)

    • [🔑 超越密码:2FA 与 Passkey](#🔑 超越密码:2FA 与 Passkey)

    • [🚪 三道门与三层安全](#🚪 三道门与三层安全)

  • [📚 延伸阅读文献](#📚 延伸阅读文献)


📝 前言

这篇题解没有源代码,只有伪代码。

作为一名信奥教练,我不提倡复制粘贴。我见过太多学生搜到题解、复制、粘贴、提交、AC------代码跑通了,脑子没跑通。下次遇到变体题,还是不会。

伪代码剥掉了语言的壳,只留算法的骨架。你看不到 #include,看不到 cincout,看不到那些让你以为"我会了"的语法细节。你能看到的只有:这一步做什么、下一步做什么、为什么这么做。

如果你是路过的友友,已经在这道题上挣扎了很久------先去喝杯水,回来重新看看自己卡在哪一步。是没读懂题意?是思路方向偏了?还是代码有 bug 但逻辑其实对?大多数时候不是不会,是走偏了。偏了不可怕,可怕的是偏了之后直接放弃,去抄一份能 AC 的代码。抄完你以为你懂了,其实你只是搬了别人的结论。

除非你时间真的紧张------比赛临近、作业要交------那种情况先 AC 再说,能理解。但平时练习,给自己一点耐心。先自己想、自己写、自己调,跑不过了再来看伪代码:你的思路和这里差在哪一步。那一步,就是你真正学到的东西。


🔍 三道题在考什么

三道题都是"加密与安全"主题,但覆盖的环节不同:

B4500 凯撒密码 B4449 密码强度 B3843 密码合规
考什么 从已知明密文对推断偏移量,解密新密文 判断密码是否满足最低安全要求 判断密码是否符合注册规则
安全环节 加密/解密 强度策略 合规校验
核心操作 模运算 + 字符偏移 长度判断 + 字符类型检测 逗号分割 + 多条件校验
现实对应 古典密码学 密码策略(NIST 指南) 用户注册系统的密码校验

B4500 是加密------把信息变成看不懂的形式,只有知道偏移量的人能还原。

B4449 是强度策略------什么样的密码才算"够安全",太短的不行、太简单的不行。

B3843 是合规校验------用户注册时,密码必须满足一套规则才能通过。这是每个有用户系统的网站都在做的事。

三道题恰好对应了用户系统安全的三道门:加密传输、强度要求、合规验证


🏛️ B4500:凯撒密码

💡 B4500 思路

题目给三行:已知明文、已知密文、待解密密文。从第一对明密文算出偏移量,然后用这个偏移量逆向解密第三行。

偏移量 = 密文首字符 - 明文首字符。解密时,对每个密文字符减去偏移量,用模 26 处理越界(A 往前偏 3 变成 X)。

📝 B4500 伪代码

text 复制代码
读取 明文 code
读取 已知密文 decode
读取 待解密密文 new_code

偏移量 = decode[0] - code[0]        // 从首字符推断偏移量

对 new_code 中每个字符 c:
    原始位置 = c - 'A'               // 转成 0-25
    解密位置 = (原始位置 - 偏移量 + 26) % 26    // 减偏移,+26 防负数,%26 处理回绕
    输出字符 = 解密位置 + 'A'          // 转回字母

🎯 B4500 关键点

偏移量从首字符推断。 shift = decode[0] - code[0]。样例中 D - A = 3,说明加密时每个字母向后移了 3 位。解密就反过来减 3。

用样例追踪:

密文字符 ASCII 位置 减偏移 3 +26 防负 %26 明文字符
W 22 19 19 19 T
K 10 7 7 7 H
H 7 4 4 4 E
T 19 16 16 16 Q
X 23 20 20 20 U
L 11 8 8 8 I

输出:THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG

+26 的作用。 如果密文字符的位置小于偏移量(比如 A=0,偏移 3,0-3=-3),结果是负数,C++ 的 % 对负数保留符号。加 26 再取模确保结果在 0-25 范围内:(-3 + 26) % 26 = 23 = X

凯撒密码为什么"非常容易被破解"。 题目背景自己说了。偏移量只有 25 种可能(1-25),暴力枚举全部、看哪个结果是有意义的英文,几秒就破。凯撒密码的安全性等于零------它是密码学的起点,但不是终点。


💪 B4449:密码强度

💡 B4449 思路

读入 T 组密码,每组检查三个条件:长度≥8、含大写字母、含数字。三个都满足输出 Y,否则 N。

代码用 continue 提前跳过短密码(长度<8 直接 N,不继续检查字符),这是一个合理的提前终止优化。

📝 B4449 伪代码

text 复制代码
读取 T

对每组密码 s:
    有大写 = false
    有数字 = false

    如果 s 长度 < 8:
        输出 "N"
        继续                     // 提前终止,不再检查字符

    对 s 中每个字符 c:
        如果 c 是大写字母:  有大写 = true
        如果 c 是数字:      有数字 = true

    如果 有大写 且 有数字:
        输出 "Y"
    否则:
        输出 "N"

🎯 B4449 关键点

提前终止。 长度<8 直接 N,不需要扫描字符。对于 T=100、每组最多 100 字符,最坏 10⁴ 次检查,毫无压力。但提前终止是良好习惯------能跳过的计算就跳过。

用样例追踪:

密码 长度≥8 有大写 有数字 结果
PAs1s2an 8 ✓ P, A ✓ 1, 2 ✓ Y
1a2bCql3 8 ✓ C ✓ 1, 2, 3 ✓ Y
Pa12bsna 8 ✓ P ✓ 1, 2 ✓ Y
ab1da3cd 8 ✓ 1, 3 ✓ N
Paabdbcd 8 ✓ P ✓ N
Pa2 3 ✗ --- --- N

两个布尔变量的"接力"。 has_uphas_num 像两个开关,扫描时只要碰到对应类型的字符就把开关打开。扫描结束后两个开关都亮着才算安全。如果只亮一个(或都不亮),不安全。

B4449 和 B3843 的区别。 B4449 的规则更宽松------只要有大写和数字就行,不限制小写和特殊字符。B3843 的规则更严格------必须满足字符集限制、长度范围、组合要求和特殊字符。前者像"够不够安全"的底线检查,后者像"符不符合规则"的格式校验。


✅ B3843:密码合规

💡 B3843 思路

输入是逗号分隔的多个密码。对每个密码段检查四条规则:字符集(只能是小写、大写、数字、!@#KaTeX parse error: Expected 'EOF', got '#' at position 45: ...两种)、至少一个特殊字符(!@#̲之一)。全满足才输出。

代码用 k 标记每个密码段的起始位置,遇到逗号时处理 ki 之间的字符段,然后 k = i+1 跳到下一段。末尾手动加一个逗号确保最后一段被处理。

📝 B3843 伪代码

text 复制代码
读取字符串 a
a 末尾追加 ','               // 确保最后一段被逗号触发处理

段起点 k = 0

对 i = 0 到 a 长度-1:
    如果 a[i] == ',':
        长度 = 0
        有小写 = false, 有大写 = false, 有数字 = false, 有特殊 = false

        对 j = k 到 i-1:
            长度++
            如果 a[j] 是小写字母:  有小写 = true
            否则如果 a[j] 是大写字母:  有大写 = true
            否则如果 a[j] 是数字字符:  有数字 = true     // 必须用 '0' 和 '9',不是 0 和 9
            否则如果 a[j] 是 ! @ # $ 之一:  有特殊 = true
            否则:
                有特殊 = false            // 非法字符
                跳出内层循环

        如果 长度 6-12 且 有特殊 且 (至少两种类型为 true):
            输出 a[k] 到 a[i-1]          // 输出合规密码

        k = i + 1                        // 跳到下一段起点

🎯 B3843 关键点

逗号分割的标准操作。 末尾加逗号 + 遇逗号触发处理 + k = i+1 跳段。这是处理"分隔符切分字符串"的经典模式,在 CSV 解析、命令行参数解析中反复出现。

字符类型检测的 if-else 链。if-else if 逐个判断字符属于哪类。一旦不属于任何合法类别,立刻 break 并标记不合规------非法字符直接一票否决。

用样例追踪:

密码段 长度 小写 大写 数字 特殊 非法字符 合规
seHJ12!@ 8 ✓ 输出
sjdkffH$123 11 ✓ 输出
sdf!@&12HDHa! 14 --- --- --- --- & 是非法
123&^YUhg@! 12 --- --- --- --- ^ 是非法

"至少两种类型"的逻辑。 原始代码的条件很长:(small&&big || small&&number || big&&number || small&&big&&number) && fu。这其实是"小写、大写、数字中至少选两种"的展开形式。更简洁的写法是 (small+big+number >= 2) && fu------把布尔值当整数加,和≥2 就是至少两种。


⚖️ 三道门的对比

B4500 凯撒密码 B4449 密码强度 B3843 密码合规
安全环节 加密/解密 强度策略 合规校验
输入 明文+密文+待解密密文 T 组密码 逗号分隔的多组密码
核心操作 模运算 + 字符偏移 长度+字符类型检测 分割+多条件校验
判断逻辑 算偏移→逆向偏移 三个条件全满足 四条规则全满足
复杂度 O(L) O(T × L) O(N),N 为总字符数
现实对应 古典密码学 NIST 密码策略 用户注册系统

B4500 是"把信息加密",B4449 是"检查密码够不够强",B3843 是"检查密码符不符合规则"。一个管传输安全,一个管密码质量,一个管格式合规。三个合在一起,就是大部分用户系统的密码安全基础流程。


⚠️ 注意事项

  • B4500 的 +26 防负数 :C++ 中负数取模结果仍为负数(如 -3 % 26 = -3),必须先 +26 再取模才能保证结果在 0-25 范围。

  • B4500 的偏移量方向shift = decode[0] - code[0](密文 - 明文),解密时是减去偏移量。如果搞反了方向(用明文 - 密文),解密会变成加密。

  • B4449 的提前终止continue 跳过短密码后不再检查字符,这是正确的------长度不够其他条件不用看。但注意 has_uphas_num 要在每组密码开始时重置。

  • B3843 的数字判断:'0' 不是 0a[j]>='0'&&a[j]<='9' 检查的是字符 '0' 到 '9'(ASCII 48-57)。如果写成 a[j]>=0&&a[j]<=9,检查的是 ASCII 值 0-9(控制字符:NULL、SOH、STX......),没有任何可打印字符会匹配。这是学生最常见的混淆------数字 0 和字符 '0' 是两个东西 。数字 0 的 ASCII 值是 48,不是 0。'0' 是字符常量,0 是整数常量。少了两个引号,逻辑完全不同。
  • B3843 的逗号追加a += ',' 是确保最后一段密码被处理的关键技巧。不追加的话,最后一段没有逗号结尾,不会被触发处理。

  • B3843 的"至少两种"展开 :原始代码把条件完全展开成四项 OR,更简洁的写法是 (small + big + number >= 2)


🌳 延伸:从凯撒密码到现代密码学

你说这三道题"都是与加密相关",而且"大部分用户系统需求都会用到"。没错------它们分别对应了用户系统安全的三个核心问题:怎么加密、密码够不够强、密码符不符合规则。这三道门背后,是密码学 2000 年的进化史和现代安全工程的完整体系。

📜 密码学 2000 年进化史

B4500 的凯撒密码,是密码学有记载的起点(Brief History of Encryption)

时期 技术 原理 和 B4500 的关系
公元前 50 年 凯撒密码 固定偏移替换 就是 B4500 本身
1553 年 维吉尼亚密码(Vigenère) 多表替换,用关键词控制偏移 凯撒的升级版------不同位置用不同偏移
1918 年 Enigma 转子机 机械式多转子替换 凯撒的终极版------每天换初始状态(Cryptography History)
1977 年 RSA 算法 大数分解困难 从"替换"到"数学难题"的范式转变(信息安全基础)
2001 年 AES 标准 置换-替换网络 全球加密标准,至今未破(CrypTool --- Geschichte)
2024 年 后量子密码 格密码等数学结构 抗量子计算机的下一代密码

凯撒密码的偏移量只有 25 种可能,暴力枚举几秒就破(Quantum Cryptography)。维吉尼亚用关键词控制偏移,安全性提升了很多,但 1863 年被 Kasiski 方法破。Enigma 每天换设置,看起来不可破,但 1939 年波兰密码局和图灵的 Bletchley Park 团队成功破译------二战因此缩短了至少两年 (Cryptography History)

RSA 不再是"替换",而是利用数学难题------分解两个大质数的乘积极其困难。AES 是对称加密的全球标准,密钥长度 128/192/256 位,暴力破解需要 10⁶⁰ 年------宇宙年龄的 10⁵⁰ 倍。

你今天在 B4500 里做的 (char - 'A' - shift + 26) % 26,和 AES 的置换-替换网络,本质上做的是同一件事------把信息变成只有持有密钥的人才能还原的形式。区别只在于:凯撒的密钥空间是 25,AES-256 的密钥空间是 2²⁵⁶。


🔒 密码存储:为什么不能存明文

B4449 和 B3843 检查的是"密码够不够强"。但密码检查完之后呢?用户的密码存在哪里?

绝对不能存明文。 如果数据库被拖库(SQL 注入、备份泄露),所有用户的密码直接暴露(Security of Credentials)。攻击者还能用同一组邮箱+密码去撞库其他平台------一次泄露引发连锁灾难(Web 服务密码存储安全)

正确做法是哈希 + 加盐 (OWASP Password Storage Cheat Sheet)

text 复制代码
用户注册:
    密码 → 加盐 → 哈希函数(慢速) → 存储哈希值

用户登录:
    输入密码 → 加同样的盐 → 哈希 → 和存储的哈希值比对
    相同 → 通过    不同 → 拒绝

哈希(Hash)不是加密。 加密可逆------有密钥就能解密还原。哈希不可逆------从哈希值反推密码只能靠暴力尝试(Best practices for password hashing)

盐(Salt)的作用。 如果不加盐,两个用户用同一密码,哈希值相同------攻击者用预计算表(彩虹表)可以秒破。加盐后,每个用户的盐不同,同一密码的哈希也不同,彩虹表失效(What Is a Password Salt)

算法 特点 推荐度
MD5 / SHA-1 太快,暴力破解成本低 ❌ 不推荐
bcrypt 内置加盐,可调成本因子 ✓ 推荐
scrypt 内存困难型,抗 GPU 破解 ✓ 推荐
Argon2id 2015 年密码哈希竞赛冠军 ✓ 最推荐

OWASP 2024 推荐使用 Argon2id,其次是 bcrypt 或 PBKDF2(OWASP Password Storage)


📋 NIST 2025 密码新规

B4449 要求"大写+数字",B3843 要求"小写+大写+数字+特殊字符至少两种"。这些规则在 2017 年之前是行业标配。但 NIST 2025 年更新了 SP 800-63B,推翻了很多旧规则 (NIST 2025 Password Recommendations)

旧规则 NIST 2025 新规 理由
要求大小写+数字+特殊字符混合 取消复杂度规则 用户被迫加 !1 在末尾,实际没提升安全性(NIST SP 800-63B)
定期更换密码 取消定期更换 除非确认泄露(NIST 2025) 用户会循环用旧密码
最短 8 字符 最短 8,推荐 15,最长 ≥64 长度比复杂度重要------correct-horse-battery-stapleTr0ub4dor&3 更安全(NIST 2025 Refresh)
无泄露检查 必须筛查已泄露密码 用 Have I Been Pwned 等数据库检查(NIST SP 800-63B)

NIST 的核心观点是:复杂度规则让用户写出 Password1! 这种"满足规则但不安全"的密码。长度比复杂度重要得多 (NIST 2025)

B4449 和 B3843 用的还是旧规则------这是 GESP 考试的简化版本,不是工业标准。但它们教会学生的核心概念是对的:密码需要满足一定要求才能使用。只是实际工业中,要求的内容在变化------从"够复杂"转向"够长+没泄露过"。


🔑 超越密码:2FA 与 Passkey

密码不是终点。现代系统正在超越密码:

技术 原理 和三道题的关系
2FA / MFA 密码 + 手机验证码/认证器 B4449 的"强度"升级为"多因素"
FIDO2 / Passkey 设备生物识别 + 公钥签名 彻底取代密码,B4449/B3843 的规则不再需要
OAuth / SSO 第三方身份提供者 不再自己存密码,交给 Google/Apple
Have I Been Pwned 密码泄露数据库 B4449 的"强度检查"升级为"泄露检查"

NIST 2025 特别强调抗钓鱼的多因素认证(phishing-resistant MFA) ------FIDO2/Passkey 是推荐方向(NIST 2025 Refresh)。未来的趋势是:密码逐渐退场,设备+生物识别接管。


🚪 三道门与三层安全

把三道题和延伸放在一起,恰好覆盖了用户系统安全的完整链路:

层级 洛谷题 工业对应 做什么
加密传输 B4500 凯撒密码 AES-256 / TLS 数据在传输中加密,第三方看不到
密码质量 B4449 密码强度 NIST SP 800-63B 密码够长、没泄露过
合规校验 B3843 密码合规 用户注册系统 密码符合字符集和组合规则
安全存储 --- Argon2id + Salt 密码哈希后存储,拖库不泄露
多因素 --- 2FA / FIDO2 超越密码,防钓鱼

B4500 管传输------信息在通道中加密。B4449 管质量------密码本身够不够强。B3843 管格式------密码符不符合注册规则。再加上存储安全(哈希+盐)和多因素认证,就是一套完整的用户系统安全方案。

你今天在洛谷上写的三段代码,对应的是用户注册系统的三个核心函数:encrypt()checkStrength()validatePassword()。每家有用户系统的公司------从微信到银行------都在调用这三个函数的工业版。


📚 延伸阅读文献

标准
  1. NIST. SP 800-63B: Digital Identity Guidelines --- Authentication and Authenticator Management (2025 Revision). (NIST Official PDF) ------ 美国国家标准与技术研究院的密码认证指南,2025 年取消复杂度规则。
  2. NIST. SP 800-63B (2017 Original) . (NIST Official) ------ 2017 年原版,首次提出取消定期更换密码。
  3. IETF. Best Practices for Password Hashing and Storage (Draft). (IETF) ------ 密码哈希存储的 IETF 最佳实践。
论文
  1. K. Pandya et al. Brief History of Encryption . International Journal of Computer Applications, 2015. (IJCA) ------ 从古代到现代的密码学历史综述。
  2. N. Gisin et al. Quantum Cryptography . Reviews of Modern Physics, 2002. (arXiv) ------ 量子密码学综述,含凯撒密码到量子密钥分发的历史脉络。
在线资源
  1. 洛谷. B4500 GESP202603 三级 凯撒密码 . https://www.luogu.com.cn/problem/B4500
  2. 洛谷. B4449 GESP202512 三级 密码强度 . https://www.luogu.com.cn/problem/B4449
  3. 洛谷. B3843 GESP202306 三级 密码合规 . https://www.luogu.com.cn/problem/B3843
  4. OWASP Password Storage Cheat Sheet . https://github.com/OWASP/CheatSheetSeries/.../Password_Storage_Cheat_Sheet.md ------ OWASP 密码存储最佳实践。
  5. NIST 2025 Password Recommendations: What's Changed . https://www.captaindns.com/.../nist-2025-password-recommendations ------ NIST 2025 密码新规解读。
  6. Your Password Policy Is Due for a 2025 Refresh . https://blogs.reliablepenguin.com/.../nist-2025 ------ NIST 2025 更新详解。
  7. Cryptography History --- From Ancient Secrets to Modern Security . https://www.bnitindia.com/blog/cryptography-history ------ 密码学历史时间线。
  8. CrypTool --- Geschichte der Kryptografie . https://www.cryptool.org/de/education/history/ ------ 密码学教育工具,含完整历史时间线。
  9. What Is a Password Salt and Why Does It Matter? https://www.panicvault.org/.../password-salt-explained ------ 密码加盐原理详解。
  10. Security of Credentials: Algorithms and Techniques for Storing Passwords . (IBIMA Publishing) ------ 密码存储算法综述。
推荐教材
  • B. Schneier. Applied Cryptography (2nd Edition). Wiley, 1996. ------ 密码学经典教材,从凯撒到 AES 全覆盖。

  • W. Stallings. Cryptography and Network Security (7th Edition). Pearson, 2017. ------ 网络安全与密码学标准教材。

  • A. J. Menezes, P. C. van Oorschot, S. A. Vanstone. Handbook of Applied Cryptography. CRC Press, 1996. ------ 应用密码学手册,免费在线版。


本文标签:#算法 #密码学 #凯撒密码 #密码强度 #密码合规 #NIST #Argon2 #洛谷题解 #信奥 #C++ #入门

本文首发于 CSDN,作者:HugoStudio_SWAN

相关推荐
小五传输1 小时前
FTP替代怎么做?医院文件安全传输选型与迁移指南
大数据·运维·安全
雾里看山1 小时前
源码目录、构建目录与 out-of-source build
c++·软件构建·cmake
枫叶林FYL2 小时前
【群体智能集群控制工程实践】第3章 一致性协同算法
算法
禹凕2 小时前
滑动窗口算法实战指南
python·算法
DisonTangor2 小时前
【腾讯混元雪耻归来】 Hy4 preview:770B 参数 MoE 旗舰模型,1M 上下文全面开源
人工智能·算法·开源·aigc·腾讯云·腾讯云ai代码助手
luckystar513~2 小时前
Hermes 实战 :系列收官/生产化——安全审计与运维
运维·人工智能·安全·agent·智能体开发·hermes实战·智能体网关
一条破秋裤2 小时前
16_TIM编码器接口测速
笔记·stm32·学习
tju新生代魔迷3 小时前
Verilog HDL 学习笔记(十)| 第10章 时序和延迟
笔记·学习·fpga开发
幼儿园蛋小黄3 小时前
嵌入式学习总结:从入门到实战的完整路径
学习