Created
March 11, 2022 08:24
-
-
Save he426100/4a35f0eb740a80ab167110fb846ee01b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| declare(strict_types=1); | |
| return [ | |
| 'key' => '', // Array.from(s).sort(() => Math.random() > 0.5 ? -1 : 1).join('') | |
| 'base' => 0 | |
| ]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| declare(strict_types=1); | |
| namespace org; | |
| use think\facade\Config; | |
| /** | |
| * Class InviteCode | |
| * 邀请码生成类 | |
| * @link https://gist.github.com/guanguans/52b9136e86c1a86ab0d51747e841537d | |
| * @link https://www.albinwong.com/6x174dD7ZyjPQvpX.html | |
| * @link https://xjwblog.com/?p=645 | |
| * @link https://learnku.com/articles/51069 | |
| * | |
| * ``` | |
| * $inviteCode = new org\InviteCode(); | |
| * var_dump($inviteCode->encode(1)); // string(6) "VQWKGR" | |
| * var_dump($inviteCode->decode("VQWKGR")); // int(1) | |
| * ``` | |
| * | |
| */ | |
| final class InviteCode | |
| { | |
| /** | |
| * @var string | |
| */ | |
| private $key; // Array.from(s).sort(() => Math.random() > 0.5 ? -1 : 1).join('') | |
| /** | |
| * @var int | |
| */ | |
| private $octal; | |
| /** | |
| * @var int | |
| */ | |
| private $base = 0; | |
| public function __construct() | |
| { | |
| $config = Config::get('invite_code'); | |
| // 注意这个key里面不能出现数字 0,否则当`求模=0`会重复的 | |
| $this->key = $this->clear($config['key']); | |
| // 多少进制 | |
| $this->octal = strlen($this->key); | |
| // 加一个基数,避免出现补零 | |
| $this->base = $config['base']; | |
| } | |
| /** | |
| * encode id to code | |
| * | |
| * @param integer $id | |
| * @param integer $length | |
| * @return string | |
| */ | |
| public function encode(int $id, int $length = 6): string | |
| { | |
| $code = ''; | |
| // 转进制 | |
| $num = $this->base + $id; | |
| while ($num > 0) { | |
| $mod = $num % $this->octal; | |
| $num = ($num - $mod) / $this->octal; | |
| $code = $this->key[$mod] . $code; | |
| } | |
| return str_pad($code, $length, '0', STR_PAD_LEFT); // 不足用0补充; | |
| } | |
| /** | |
| * decode code to id | |
| * | |
| * @param string $code | |
| * @return integer | |
| */ | |
| public function decode(string $code): int | |
| { | |
| //移除左侧的 0 | |
| if (strrpos($code, '0') !== false) { | |
| $code = substr($code, strrpos($code, '0') + 1); | |
| } | |
| $len = strlen($code); | |
| $code = strrev($code); | |
| $num = 0; | |
| for ($i = 0; $i < $len; $i++) { | |
| $num += strpos($this->key, $code[$i]) * pow($this->octal, $i); | |
| } | |
| return (int)$num - $this->base; | |
| } | |
| /** | |
| * 检查邀请码是否正确 | |
| * | |
| * @param string $code | |
| * @return boolean | |
| */ | |
| public function checkCode(string $code): bool | |
| { | |
| $key = $this->key; | |
| return count(array_filter(str_split($code), function ($e) use ($key) { | |
| return strpos($key, $e) !== false; | |
| })) === strlen($code); | |
| } | |
| /** | |
| * @param string $str | |
| * | |
| * @return string | |
| */ | |
| private function clear(string $str): string | |
| { | |
| $uniqueStr = trim(implode('', array_unique(str_split($str)))); | |
| return str_replace('0', '', $uniqueStr); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment