PHP如何基于指定字符串生成无存储6位邮箱验证数字验证码
无存储6位邮箱验证码PHP实现方案
PHP没有原生的直接传入多参数输出指定位数数字验证码的函数,但你可以通过组合原生哈希、字符串处理函数快速实现符合需求的功能,不需要服务端存储任何验证码数据。
实现逻辑
核心是把用户邮箱、自定义密钥、按有效期取整的时间戳三类参数拼接后做哈希,再把哈希结果转换为固定6位数字即可。加时间戳的目的是给验证码增加有效期,避免生成的验证码永久有效带来的安全风险。
完整代码实现
验证码生成函数
function generateVerificationCode(string $email, string $secretKey, int $expireMinutes = 10): string { // 按有效期取整时间戳,保证有效期内生成的验证码一致 $timeSlot = floor(time() / ($expireMinutes * 60)); $rawStr = $email . $secretKey . $timeSlot; $hash = hash('sha256', $rawStr); // 取哈希前8位十六进制转十进制,模1000000得到6位数字,补前导零保证固定6位 return sprintf('%06d', hexdec(substr($hash, 0, 8)) % 1000000); }
验证码验证函数
function verifyVerificationCode(string $email, string $secretKey, string $inputCode, int $expireMinutes = 10): bool { $currentSlot = floor(time() / ($expireMinutes * 60)); // 同时校验当前和上一个时间槽的验证码,避免临界时间点用户刚收到就过期的问题 $validSlots = [$currentSlot, $currentSlot - 1]; foreach ($validSlots as $slot) { $rawStr = $email . $secretKey . $slot; $hash = hash('sha256', $rawStr); $calculatedCode = sprintf('%06d', hexdec(substr($hash, 0, 8)) % 1000000); // 用hash_equals做防时序攻击的字符串比较 if (hash_equals($calculatedCode, $inputCode)) { return true; } } return false; }
使用示例
生成验证码发送阶段
// 你的自定义密钥,注意保密不要泄露 $customSecret = 'd%kDh^l1285'; $userTargetEmail = 'test123@gmail.com'; $code = generateVerificationCode($userTargetEmail, $customSecret); // 此处添加将$code发送到用户邮箱的逻辑即可
用户回填验证码校验阶段
$userInputCode = $_POST['verification_code']; // 获取用户提交的6位验证码 if (verifyVerificationCode($userTargetEmail, $customSecret, $userInputCode)) { // 验证通过,执行邮箱修改逻辑 } else { // 验证码错误或已过期,返回提示 }
注意事项
- 自定义密钥要保证足够复杂且不对外泄露,这是该方案安全性的核心
- 代码默认验证码有效期为10分钟,可根据自身需求调整
$expireMinutes参数 - 你已做的请求频次限制,可以有效避免6位验证码被暴力破解的风险
内容的提问来源于stack exchange,提问作者prof chaos
相关产品推荐
相关产品推荐

