PHP加密解密类:专用于数字ID与URL的混淆方案
在Web开发中,直接暴露数据库自增ID往往带来安全隐患,如泄露业务规模或引发遍历攻击。本文展示一个轻量级的PHP数字加密解密类,通过对数字进行字符替换和补位混淆,生成固定的非连续字符串,有效保护URL参数和内部标识。
核心设计目标
该方案主要解决以下问题:
- 隐藏数据总量:通过非递增的密文,让外部无法推断数据库记录总数。
- 防止遍历:即使获取相邻ID的密文,也无法轻易推算出其他ID。
- URL友好性:输出为字母数字混合串,适合嵌入网址参数。
注意:此类算法属于“混淆”而非高强度的密码学加密(如AES)。其目的是增加逆向难度和减少明文曝光,不适合存储密码等极高敏感信息。
算法原理简述
算法基于自定义的字符映射表,主要步骤如下:
- 初始化:定义一个包含62个字符(a-z, A-Z, 0-9)的基础字符串。
- 分段提取:
标记区:取前N位,用于编码原始数字的长度。替换区:取紧接着的10位,建立原数字0-9到密文字符的映射。补位区:剩余字符用于填充密文,使总长度固定并增加复杂度。
- 编码过程:根据输入数字长度确定标记位,计算补位字符,并通过映射表替换数字部分。
- 解码过程:读取首位确定数字长度,截取对应长度的尾部密文,通过反向映射还原数字。
完整代码实现
以下是完整的 XDeode 类实现。使用时需引入该类文件,实例化后即可调用 encode() 和 decode() 方法。
<?php
/**
* 加密解密类
* 该算法仅支持加密数字。比较适用于数据库中id字段的加密解密,以及根据数字显示url的加密。
* @author 深秋的竹子
* @version alpha
*/
class XDeode{
private $strbase = "Flpvf70CsakVjqgeWUPXQxSyJizmNH6B1u3b8cAEKwTd54nRtZOMDhoG2YLrI";
private $key,$length,$codelen,$codenums,$codeext;
function __construct($length = 9,$key = 2543.5415412812){
$this->key = $key;
$this->length = $length;
$this->codelen = substr($this->strbase,0,$this->length);
$this->codenums = substr($this->strbase,$this->length,10);
$this->codeext = substr($this->strbase,$this->length + 10);
}
function encode($nums){
$rtn = "";
$numslen = strlen($nums);
//密文第一位标记数字的长度
$begin = substr($this->codelen,$numslen - 1,1);
//密文的扩展位
$extlen = $this->length - $numslen - 1;
$temp = str_replace('.', '', $nums / $this->key);
$temp = substr($temp,-$extlen);
$arrextTemp = str_split($this->codeext);
$arrext = str_split($temp);
foreach ($arrext as $v) {
$rtn .= $arrextTemp[$v];
}
$arrnumsTemp = str_split($this->codenums);
$arrnums = str_split($nums);
foreach ($arrnums as $v) {
$rtn .= $arrnumsTemp[$v];
}
return $begin.$rtn;
}
function decode($code){
$begin = substr($code,0,1);
$rtn = '';
$len = strpos($this->codelen,$begin);
if($len!== false){
$len++;
$arrnums = str_split(substr($code,-$len));
foreach ($arrnums as $v) {
$rtn .= strpos($this->codenums,$v);
}
}
return $rtn;
}
}
// 使用示例
$begin = 9950;
$end = $begin + 50;
$obj = new XDeode(9);
for($i=$begin;$i<$end;$i++){
$en = $obj->encode($i);
$de = $obj->decode($en);
echo "[{$i}]=[{$en}]=[{$de}]<br/>";
}
?>
运行结果验证
执行上述代码后,控制台/浏览器将输出加密前后的对比数据。可以看出,连续的整数被转换为了看似随机的短字符串,且解密能完美还原原始值。
[9950]=[vmizxPPga]=[9950]
[9951]=[vSNSSPPgk]=[9951]
[9952]=[vNQNyPPgV]=[9952]
[9953]=[vyyJJPPgj]=[9953]
[9954]=[vNzQzPPgq]=[9954]
[9955]=[vyNzmPPgg]=[9955]
[9956]=[vXxSNPPge]=[9956]
[9957]=[vXJJJPPgW]=[9957]
[9958]=[vXziQPPgU]=[9958]
[9959]=[viXxSPPgP]=[9959]
[9960]=[vQxmyPPea]=[9960]
[9961]=[viJyJPPek]=[9961]
集成建议
- 数据库字段:建议在表中保留原始ID作为主键或唯一索引,新增一列存储加密后的ID,或在应用层动态处理。
- 路由匹配:在接收到前端传参时,先调用
decode()恢复原始ID,再进行数据库查询。 - 配置灵活性:
__construct中的$key可作为盐值修改,若希望不同项目拥有不同密文风格,可传入不同的Key值。
以上就是PHP针对数字ID进行加密和解密的详细内容,更多关于PHP数据安全与URL优化的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









