Skip to content

Instantly share code, notes, and snippets.

@he426100
Created March 11, 2022 08:24
Show Gist options
  • Select an option

  • Save he426100/4a35f0eb740a80ab167110fb846ee01b to your computer and use it in GitHub Desktop.

Select an option

Save he426100/4a35f0eb740a80ab167110fb846ee01b to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
return [
'key' => '', // Array.from(s).sort(() => Math.random() > 0.5 ? -1 : 1).join('')
'base' => 0
];
<?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