132 lines
2.9 KiB
PHP
132 lines
2.9 KiB
PHP
<?php
|
||
|
||
namespace app;
|
||
|
||
use extend\ba\Random;
|
||
|
||
class InvitationCodeUtil
|
||
{
|
||
/**
|
||
* 自定义进制字符集(30进制)
|
||
* 避免 0、1、O、I 混淆字符
|
||
*/
|
||
private static array $r = ['M', 'J', 'U', 'D', 'Z', 'X', '9', 'C', '7', 'P', 'E', '8', '6', 'B', 'G', 'H', 'S', '2', '5', 'F', 'R', '4', 'Q', 'W', 'K', '3', 'V', 'Y', 'T', 'N'];
|
||
|
||
/**
|
||
* 补位字符
|
||
*/
|
||
private static string $b = 'A';
|
||
|
||
/**
|
||
* 进制长度
|
||
*/
|
||
private static int $binLen = 30;
|
||
|
||
/**
|
||
* 最小长度
|
||
*/
|
||
private static int $s = 6;
|
||
|
||
/**
|
||
* 补位字符串 - 生成注册码用
|
||
*/
|
||
private static string $re = 'REGISTER';
|
||
|
||
/**
|
||
* 补位字符串 - 生成序列码用
|
||
*/
|
||
private static string $e = 'KSLFXFR';
|
||
|
||
/**
|
||
* 根据ID生成六位注册邀请码
|
||
*
|
||
* @param int $id
|
||
* @return string
|
||
*/
|
||
public static function toRegisteredCode(int $id): string
|
||
{
|
||
$str = self::encodeBase($id);
|
||
if (strlen($str) < self::$s) {
|
||
$pad = substr(self::$re, 0, self::$s - strlen($str));
|
||
$str .= $pad;
|
||
}
|
||
return $str;
|
||
}
|
||
|
||
/**
|
||
* 根据ID生成六位序列码
|
||
*
|
||
* @param int $id
|
||
* @return string
|
||
*/
|
||
public static function toSerialCode(int $id): string
|
||
{
|
||
$str = self::encodeBase($id);
|
||
if (strlen($str) < self::$s) {
|
||
$pad = substr(self::$e, 0, self::$s - strlen($str));
|
||
$str .= $pad;
|
||
}
|
||
return $str;
|
||
}
|
||
|
||
/**
|
||
* 将邀请码还原为 ID
|
||
*
|
||
* @param string $code
|
||
* @return int
|
||
*/
|
||
public static function codeToId(string $code): int
|
||
{
|
||
$chars = str_split($code);
|
||
$res = 0;
|
||
|
||
foreach ($chars as $i => $ch) {
|
||
if ($ch === self::$b) {
|
||
break;
|
||
}
|
||
|
||
$index = array_search($ch, self::$r, true);
|
||
if ($index === false) {
|
||
continue;
|
||
}
|
||
|
||
$res = $i === 0 ? $index : $res * self::$binLen + $index;
|
||
}
|
||
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 雪花 ID(需引入 PHP 雪花 ID 工具)
|
||
* 推荐使用: https://github.com/Gerardojbaez/laravel-snowflake 或你自己的封装
|
||
*
|
||
* @return int
|
||
*/
|
||
public static function getSnowFlakeId(): int
|
||
{
|
||
// 简化版本,实际应使用类库如 Godruoyi\Snowflake
|
||
if (!class_exists('Snowflake')) {
|
||
throw new \RuntimeException("Snowflake class not found.");
|
||
}
|
||
return Random::generateRandomPrefixedId();
|
||
}
|
||
|
||
/**
|
||
* 进制转换编码主逻辑
|
||
*
|
||
* @param int $id
|
||
* @return string
|
||
*/
|
||
private static function encodeBase(int $id): string
|
||
{
|
||
$buf = [];
|
||
do {
|
||
$index = $id % self::$binLen;
|
||
array_unshift($buf, self::$r[$index]);
|
||
$id = intdiv($id, self::$binLen);
|
||
} while ($id > 0);
|
||
|
||
return implode('', $buf);
|
||
}
|
||
}
|