程序开发过程中总是有一些自增ID信息会展现给前端,这样就给一些人可乘之机,通过遍历ID等方式获取到数据信息。
为了解决这个问题,想了很多办法,今天自己写了一个对称加密算法分享给大家。ID加密后展示到前端,后端先解密再处理。
代码如下,欢迎指正。
<?php
/**
* 整型数字对称加密,使用场景:对ID加密后展示
* 只适用整型数字
* 使用时请重新生成密钥
*/
class IntCode{
// 密钥(0-9A-Za-z)打乱,可使用str_shuffle()函数重新生成
private $key = 'PTvNKJdjOyB3niF891XCspl7rHMQIkELVqYbm20ZGUWhfze5txSRowg4uDA6ac';
public function encode($int){
//判断是否为整型
if (! is_int($int)) {
return '不是整型';
}
//将传入数字转换成十六进制分割成数组
$hexArr = str_split(dechex($int));
//将密钥分割成数组
$keyArr = str_split($this->key);
//密钥长度,推荐62
$keyLen = count($keyArr);
//随机数字
$rand = mt_rand(0, $keyLen - 1);
//将随机值压入结果开头
$str = $keyArr[$rand];
//验证码
$verfy = $keyArr[($keyLen - $rand + strlen($int)) % $keyLen];
//循环十六进制每一位数字,替换成密钥里的值
foreach ($hexArr as $v) {
$offset = hexdec($v) + $rand;
$str .= $keyArr[$offset % $keyLen];
}
//将验证码压入结果末尾并返回
return $str . $verfy;
}
public function decode($str){
//验证$str是否合法
if (! preg_match('/^[0-9a-zA-Z]{2,10}$/', $str)) {
return '字符不合法';
}
//将传入字符串分割成数组
$strArr = str_split($str);
//密钥
$key = $this->key;
//将密钥分割成数组
$keyArr = str_split($this->key);
//密钥长度
$keyLen = count($keyArr);
//十六进制数值
$hex = '';
//获取随机数
$rand = strpos($key, array_shift($strArr));
//获取验证码
$verfy = array_pop($strArr);
//循环每一个字串并转换成十六进制
foreach ($strArr as $k => $v) {
if (strpos($key, $v) >= $rand) {
$hex .= dechex(strpos($key, $v) - $rand);
} else {
$hex .= dechex($keyLen - $rand + strpos($key, $v));
}
}
//十六进制转换成十进制
$dec = hexdec($hex);
//判断验证码是否正确
if ($verfy !== $keyArr[($keyLen - $rand + strlen($dec)) % $keyLen]) {
return '校验错误,给定字符串不合法';
}
return $dec;
}
}
//以下为测试内容
$intCode = new IntCode();
// echo $intCode->encode(98445);
// echo $intCode->decode('h1xss');
for ($i=9865; $i<19800; $i++) {
$str = $intCode->encode($i);
$int = $intCode->decode($str);
echo $i . ' | ' . $int . ' | ' . $str . '<br>';
}