Hashids 是一个用于生成短、唯一的非连续ID的库,它可以将整数(如数据库中的自增ID)转换为唯一的字符串。在 PHP 中,你可以使用 hashids/hashids 这个包来实现这个功能。
首先,安装 Hashids:
composer require hashids/hashids
接下来,我们来看一下 Hashids 的基本用法:
<?php
require_once 'vendor/autoload.php';
use Hashids\Hashids;
$hashids = new Hashids();
$id = 12345;
$hash = $hashids->encode($id); // 转换为字符串
echo $hash . PHP_EOL; // 输出字符串
$decodedId = $hashids->decode($hash)[0]; // 解码回整数
echo $decodedId . PHP_EOL; // 输出整数
现在,我们来分析 Hashids 的源码。首先,创建一个新的 Hashids 实例时,会传入一些参数,如下所示:
public function __construct(
    string $salt = '',
    int $minHashLength = 0,
    string $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
) {
    // ...
}
$salt:用于加密的盐值,可以为空。$minHashLength:生成的哈希字符串的最小长度。$alphabet:用于生成哈希字符串的字符集。接下来,我们来看一下 encode() 和 decode() 方法的实现。这里只列出关键部分:
public function encode(...$numbers): string
{
    // ...
    while (count($numbers)) {
        $number = array_shift($numbers);
        $buffer = '';
        do {
            $buffer .= $this->alphabet[$number % $this->alphabetLength];
            $number = ($number - ($number % $this->alphabetLength)) / $this->alphabetLength;
        } while ($number > 0);
        $result = strrev($buffer) . $result;
    }
    // ...
    return $result;
}
public function decode(string $hash): array
{
    // ...
    $hashArray = str_split(strrev($hash));
    foreach ($hashArray as $i => $char) {
        $number += strpos($this->alphabet, $char) * pow($this->alphabetLength, $i);
    }
    // ...
    return $result;
}
encode() 方法将整数转换为字符串,它首先计算余数并将其添加到缓冲区,然后将结果反转并与之前的结果拼接。decode() 方法则是将字符串反转后,计算每个字符在字母表中的位置,然后将其相加得到原始整数。
修改建议:
$hashids = new Hashids('', 0, 'abcdefghijklmnopqrstuvwxyz!@#$%^&*()');
$hashids = new Hashids('my_salt');
$hashids = new Hashids('', 10);
总之,Hashids 是一个很好的库,可以帮助你生成短、唯一的非连续ID。你可以根据需要对其进行修改和优化。