溫馨提示×

Hashids在PHP中的源碼分析及修改建議

PHP
小樊
82
2024-08-28 18:41:47
欄目: 編程語言

Hashids 是一個用于生成短、唯一的非連續(xù)ID的庫,它可以將整數(shù)(如數(shù)據(jù)庫中的自增ID)轉(zhuǎn)換為唯一的字符串。在 PHP 中,你可以使用 hashids/hashids 這個包來實現(xiàn)這個功能。

首先,安裝 Hashids:

composer require hashids/hashids

接下來,我們來看一下 Hashids 的基本用法:

<?php
require_once 'vendor/autoload.php';

use Hashids\Hashids;

$hashids = new Hashids();

$id = 12345;
$hash = $hashids->encode($id); // 轉(zhuǎn)換為字符串
echo $hash . PHP_EOL; // 輸出字符串

$decodedId = $hashids->decode($hash)[0]; // 解碼回整數(shù)
echo $decodedId . PHP_EOL; // 輸出整數(shù)

現(xiàn)在,我們來分析 Hashids 的源碼。首先,創(chuàng)建一個新的 Hashids 實例時,會傳入一些參數(shù),如下所示:

public function __construct(
    string $salt = '',
    int $minHashLength = 0,
    string $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
) {
    // ...
}
  • $salt:用于加密的鹽值,可以為空。
  • $minHashLength:生成的哈希字符串的最小長度。
  • $alphabet:用于生成哈希字符串的字符集。

接下來,我們來看一下 encode()decode() 方法的實現(xiàn)。這里只列出關(guān)鍵部分:

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() 方法將整數(shù)轉(zhuǎn)換為字符串,它首先計算余數(shù)并將其添加到緩沖區(qū),然后將結(jié)果反轉(zhuǎn)并與之前的結(jié)果拼接。decode() 方法則是將字符串反轉(zhuǎn)后,計算每個字符在字母表中的位置,然后將其相加得到原始整數(shù)。

修改建議:

  1. 更改默認(rèn)的字母表:可以在創(chuàng)建 Hashids 實例時傳入自定義的字母表,以增加哈希字符串的復(fù)雜性。
$hashids = new Hashids('', 0, 'abcdefghijklmnopqrstuvwxyz!@#$%^&*()');
  1. 使用鹽值:為了提高安全性,可以在創(chuàng)建 Hashids 實例時傳入一個鹽值。這樣,即使兩個人使用相同的字母表,他們也會得到不同的哈希字符串。
$hashids = new Hashids('my_salt');
  1. 設(shè)置最小哈希長度:可以通過設(shè)置最小哈希長度來增加哈希字符串的長度,從而提高安全性。
$hashids = new Hashids('', 10);

總之,Hashids 是一個很好的庫,可以幫助你生成短、唯一的非連續(xù)ID。你可以根據(jù)需要對其進(jìn)行修改和優(yōu)化。

0