This commit is contained in:
2026-03-01 21:05:19 +08:00
parent 0a45a8fbb9
commit 92948fa856
39 changed files with 594 additions and 269 deletions
+231
View File
@@ -0,0 +1,231 @@
<?php
namespace support;
class Encrypt
{
/**
* 类似QQ的非连续数字ID加密
* 使用可逆的位运算混淆算法
* 特点:
* 1. 连续输入产生非连续、看起来随机的输出
* 2. 加密解密完全可逆
* 3. 输出为8位纯数字(10000000 - 99999999),类似QQ号
* 4. 支持约9000万个ID (0 - 89999999)
*/
// 最大ID值(支持9000万个ID
private static $maxId = 90000000;
// 加密结果基数(确保8位数)
private static $baseValue = 10000000;
/**
* 加密连续数字ID为非连续数字ID
* 使用基于哈希的可逆映射
* @param int $plainId 原始连续ID (0 - 89999999)
* @param int $userKey 可选的额外密钥
* @return int 加密后的非连续ID8位数)
*/
static function userIDencode($userID,$key=0):string{
if(!is_numeric(($userID))){
return $userID;
}
$userID = intval($userID);
if($userID<=100234){
return $userID.'';
}
if($userID<=102028){
return id_encode($userID);
}
$key = intval($key);
$plainId = abs(intval($userID)) % self::$maxId;
// 使用哈希函数生成伪随机序列,然后建立双射映射
// 方法:使用线性同余生成器 (LCG) 的变体
// 公式:encrypted = (a * plainId + b) mod m
// 其中 a 和 m 互质,保证可逆
// 选择一个大质数作为乘数(与9000万互质)
$a = 15485863; // 大质数,与90000000互质
$b = 2038074743; // 大常数
$m = self::$maxId;
// 加密
$encrypted = ($a * $plainId + $b + $key) % $m;
// 确保结果是8位数(10000000 - 99999999
return (self::$baseValue + $encrypted).'';
}
/**
* 解密非连续数字ID为原始连续ID
* @param int $encryptedId 加密后的非连续ID8位数)
* @param int $userKey 可选的额外密钥
* @return int 原始连续ID
*/
static function userIDDecode($userID,$key=0):string{
if(!is_numeric(($userID))){
return id_decode($userID.'');
}
if($userID<=100234){
return $userID.'';
}
$key = intval($key);
// 去除基数,得到原始混淆值
$cipherId = ($userID - self::$baseValue + self::$maxId) % self::$maxId;
// LCG解密:plain = (encrypted - b) * a^-1 mod m
$a = 15485863;
$b = 2038074743;
$m = self::$maxId;
// 计算 a 的模逆元 (使用扩展欧几里得算法)
$aInv = self::modInverse($a, $m);
// 解密
$temp = ($cipherId - $b - $key) % $m;
if ($temp < 0) $temp += $m;
$plainId = ($aInv * $temp) % $m;
return $plainId.'';
}
/**
* 使用扩展欧几里得算法计算模逆元
* 返回 x 使得 (a * x) % m = 1
*/
private static function modInverse($a, $m) {
$m0 = $m;
$x0 = 0;
$x1 = 1;
if ($m == 1) return 0;
while ($a > 1) {
// q 是商
$q = intval($a / $m);
$t = $m;
// m 是余数,处理完后 a 和 m 互换
$m = $a % $m;
$a = $t;
// 更新 x0 和 x1
$t = $x0;
$x0 = $x1 - $q * $x0;
$x1 = $t;
}
// 确保 x1 是正数
if ($x1 < 0) $x1 += $m0;
return $x1;
}
static function generateShortUniqueID($length = 8)
{
// 生成指定长度的随机字节,转为 Base64 编码并去除不必要字符
return substr(bin2hex(random_bytes($length / 2)), 0, $length);
}
static function idEncode($id = '')
{
if ($id <= 100234) {
return $id . '';
}
return id_encode($id);
}
static function idDecode($id = '')
{
$_id = intval($id);
if ($_id == $id) {
return $id;
}
return id_decode($id);
}
/**
* 生成可逆的邀请码(8位,含校验位)
* @param int $id 用户ID(需≥1000
* @return string 大写字母+数字组合
*/
static function base62Encode(int $id, $secret = 'your_secret_salt'): string
{
// 添加校验位(防止篡改)
$hash = crc32($id . $secret) % 1000;
$code_num = $id * 1000 + $hash;
// Base62 编码(0-9A-Za-z
$base62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$code = '';
while ($code_num > 0) {
$code = $base62[$code_num % 62] . $code;
$code_num = (int) ($code_num / 62);
}
// 补全到8位
return str_pad($code, 8, '0', STR_PAD_LEFT);
}
/**
* 从邀请码解析用户ID
* @return int|false 成功返回id,失败返回false
*/
static function base62Decode(string $code, $secret = 'your_secret_salt'): int|false
{
$base62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$code_num = 0;
// Base62 解码
for ($i = 0; $i < strlen($code); $i++) {
$pos = strpos($base62, $code[$i]);
if ($pos === false)
return false;
$code_num = $code_num * 62 + $pos;
}
// 分离校验位
$id = (int) ($code_num / 1000);
$hash = $code_num % 1000;
// 校验
if (crc32($id . $secret) % 1000 != $hash) {
return false;
}
return $id;
}
/**
* Aes加密
* @param mixed $str
* @param mixed $key
* @return string
*/
static function aesencode($str, $key = '')
{
if (!$key) {
$key = Config('pay.api_token');
}
if (is_array($str) || is_object($str)) {
$str = json_encode($str, JSON_UNESCAPED_UNICODE);
}
$key = hash('sha256', $key, true);
$iv = substr($key, 0, 16);
$encrypted = openssl_encrypt($str, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($encrypted);
}
/**
* Aes解密
* @param mixed $str
* @param mixed $key
* @return string
*/
static function aesdecode($str, $key = '')
{
if (!$key) {
$key = Config('pay.api_token');
}
$key = hash('sha256', $key, true);
$iv = substr($key, 0, 16);
$encrypted = base64_decode($str);
$decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
return $decrypted;
}
}
+1 -1
View File
@@ -88,7 +88,7 @@ class Utils
$token = $token ? $token : Utils::getAdminToken();
}
$url = Url::buildUrl($path);
log_alert($url);
//log_alert($url);
//log_alert($data);
$res = self::request($url, $data, $token);
//log_alert($res);