洛谷 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,看不到 cin、cout,看不到那些让你以为"我会了"的语法细节。你能看到的只有:这一步做什么、下一步做什么、为什么这么做。
如果你是路过的友友,已经在这道题上挣扎了很久------先去喝杯水,回来重新看看自己卡在哪一步。是没读懂题意?是思路方向偏了?还是代码有 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_up 和 has_num 像两个开关,扫描时只要碰到对应类型的字符就把开关打开。扫描结束后两个开关都亮着才算安全。如果只亮一个(或都不亮),不安全。
B4449 和 B3843 的区别。 B4449 的规则更宽松------只要有大写和数字就行,不限制小写和特殊字符。B3843 的规则更严格------必须满足字符集限制、长度范围、组合要求和特殊字符。前者像"够不够安全"的底线检查,后者像"符不符合规则"的格式校验。
✅ B3843:密码合规
💡 B3843 思路
输入是逗号分隔的多个密码。对每个密码段检查四条规则:字符集(只能是小写、大写、数字、!@#KaTeX parse error: Expected 'EOF', got '#' at position 45: ...两种)、至少一个特殊字符(!@#̲之一)。全满足才输出。
代码用 k 标记每个密码段的起始位置,遇到逗号时处理 k 到 i 之间的字符段,然后 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_up和has_num要在每组密码开始时重置。
- B3843 的数字判断:
'0'不是0:a[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-staple 比 Tr0ub4dor&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()。每家有用户系统的公司------从微信到银行------都在调用这三个函数的工业版。
📚 延伸阅读文献
标准
- NIST. SP 800-63B: Digital Identity Guidelines --- Authentication and Authenticator Management (2025 Revision). (NIST Official PDF) ------ 美国国家标准与技术研究院的密码认证指南,2025 年取消复杂度规则。
- NIST. SP 800-63B (2017 Original) . (NIST Official) ------ 2017 年原版,首次提出取消定期更换密码。
- IETF. Best Practices for Password Hashing and Storage (Draft). (IETF) ------ 密码哈希存储的 IETF 最佳实践。
论文
- K. Pandya et al. Brief History of Encryption . International Journal of Computer Applications, 2015. (IJCA) ------ 从古代到现代的密码学历史综述。
- N. Gisin et al. Quantum Cryptography . Reviews of Modern Physics, 2002. (arXiv) ------ 量子密码学综述,含凯撒密码到量子密钥分发的历史脉络。
在线资源
- 洛谷. B4500 GESP202603 三级 凯撒密码 . https://www.luogu.com.cn/problem/B4500
- 洛谷. B4449 GESP202512 三级 密码强度 . https://www.luogu.com.cn/problem/B4449
- 洛谷. B3843 GESP202306 三级 密码合规 . https://www.luogu.com.cn/problem/B3843
- OWASP Password Storage Cheat Sheet . https://github.com/OWASP/CheatSheetSeries/.../Password_Storage_Cheat_Sheet.md ------ OWASP 密码存储最佳实践。
- NIST 2025 Password Recommendations: What's Changed . https://www.captaindns.com/.../nist-2025-password-recommendations ------ NIST 2025 密码新规解读。
- Your Password Policy Is Due for a 2025 Refresh . https://blogs.reliablepenguin.com/.../nist-2025 ------ NIST 2025 更新详解。
- Cryptography History --- From Ancient Secrets to Modern Security . https://www.bnitindia.com/blog/cryptography-history ------ 密码学历史时间线。
- CrypTool --- Geschichte der Kryptografie . https://www.cryptool.org/de/education/history/ ------ 密码学教育工具,含完整历史时间线。
- What Is a Password Salt and Why Does It Matter? https://www.panicvault.org/.../password-salt-explained ------ 密码加盐原理详解。
- 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