新建檔案app/Services/InviteCodeService.php
<?php
namespace App\Services;
// 邀請碼服務
class InviteCodeService
{
protected $key,$num;
public function __construct()
{
$this->key = 'abcdefghjkmnpqrstuvwxyz123456789';
// 注意這個key裡面不能出現數字0 否則當 求模=0 會重複的
// 多少進位制
$this->num = strlen($this->key);
}
// 傳遞使用者id生成唯一邀請碼
public function enCode(int $user_id)
{
$code = ''; // 邀請碼
while ($user_id > 0) { // 轉進位制
$mod = $user_id % $this->num; // 求模
$user_id = ($user_id - $mod) / $this->num;
$code = $this->key[$mod] . $code;
}
$code = str_pad($code, 4, '0', STR_PAD_LEFT); // 不足用0補充
return $code;
}
// 邀請碼獲取使用者id 一般都不需要用到
function deCode($code)
{
if (strrpos($code, '0') !== false)
$code = substr($code, strrpos($code, '0') + 1);
$len = strlen($code);
$code = strrev($code);
$user_id = 0;
for ($i = 0; $i < $len; $i++)
$user_id += strpos($this->key, $code[$i]) * pow($this->num, $i);
return $user_id;
}
}
繫結到容器
看愛好,如果不想繫結就 new \App\Services\InviteCodeService
。
編輯app/Providers/AppServiceProvider.php
use App\Services\InviteCodeService;
public function register()
{
$this->app->singleton('invite_code',InviteCodeService::class);
}
測試唯一性
$max_num = 200000;
$codes = [];
for ($i = 1; $i <= $max_num; $i++)
$codes[] = app('invite_code')->enCode($i);
$i = 1;
foreach ($codes as $code){
$userId = app('invite_code')->deCode($code); // 邀請碼獲取使用者id
if( $userId != $i)
dd("邀請碼解密錯誤".$i);
$i++;
}
$unique_count = count(array_unique($codes));
dd($unique_count); // 不重複的總數
20w
資料是沒有重複的,並且邀請碼解 使用者id
也是正確的。
要注意的
$this->key
不能出現數字0
。$this->key
不能有重複的字串。 如:abccd
c
重複。
關於$this->key
$this->key
順序可以打亂的,// $this->key = 'abcdefghjkmnpqrstuvwxyz123456789'; // 沒打亂的 $this->key = 'kh8sjpdazetnmb5yw7rq4gc9fuv3216x'; // 打亂的
$this->key
長度不限制, 但是最好別太短。
如abcd
: 最大的使用者id
是4的3次方 (256)
超過256會怎麼樣? 邀請碼變成5位而已 ……. ,不好看。為使用者體驗,
$this->key
字串別加i
o
l
這些字母,因為容易混淆使用者。i
:l
l
:1
o
:0
(當然0
是不能出現的)
很相似。
Ps
生成的邀請碼位數 取決於 使用者id
可以被 取模多少次。
例
假設$this->key = abcd
那就是4進位制了。
如:使用者id
255
邀請碼4位數。
256
邀請碼5位數。
500
邀請碼5位數。
……
(所以對邀請碼位數有限定的話,聰明的你會懂的怎麼辦的吧)
32
進位制 邀請碼是4位 最大使用者id是多少?
32^4 = 1048576
扯淡
因為要做邀請碼功能,第一反應:
百度搜出來程式碼雖然能用,有重複,不理想,就改編別人程式碼了。
然後就有這篇文章了。
本作品採用《CC 協議》,轉載必須註明作者和本文連結