首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 任意進制互轉類:支持 2-36 進制、兼容 base_convert、自定義字符集

     編輯:PHP 相關知識

為什麼要重造輪子?

PHP 內建 base_convert() 功能強大,但存在已知問題:大數精度丟失(內部轉浮點運算)、字符集固定(0-9a-z)。本類提供純整數運算實現,支持自定義字符集,適合短網址、ID 混淆、邀請碼生成等場景。

類完整代碼

<?php
/**
 * 進制轉換類
 * @author sgf@funcity
 * @version 2011-02-15
 */
class Hex {
    // 字符集:0-9 A-Z,可擴展至 62 位(加 a-z)或自定義
    private static $element = array(
        '0','1','2','3','4','5','6','7','8','9',
        'A','B','C','D','E','F','G','H','I','J',
        'K','L','M','N','O','P','Q','R','S','T',
        'U','V','W','X','Y','Z'
    );
    private static $hex_min = 2;
    private static $hex_max = 36;  // 當前字符集支持上限

    /**
     * 進制轉換入口
     * @param string|int $int      輸入數值(字符串避免大數截斷)
     * @param int        $out_hex  目標進制
     * @param int        $in_hex   源進制,默認 10
     * @param bool       $use_system 是否優先使用 base_convert
     * @return string|false
     */
    public function conv($int, $out_hex, $in_hex = 10, $use_system = true) {
        // 1. 系統函數快速通道
        if ($use_system && function_exists('base_convert')) {
            return strtoupper(base_convert($int, $in_hex, $out_hex));
        }
        // 2. 同進制直接返回
        if ($out_hex == $in_hex) return $int;
        // 3. 進制範圍校驗
        if ($out_hex > self::$hex_max || $out_hex < self::$hex_min) return false;
        if ($in_hex  > self::$hex_max || $in_hex  < self::$hex_min) return false;

        // 4. 核心流程:源進制 → 十進制 → 目標進制
        $hex_10 = $this->_conv2hex10($int, $in_hex);
        return strtoupper($this->_conv_hex($hex_10, $out_hex));
    }

    /** 任意進制 → 十進制(字符串運算,無精度損失) */
    private function _conv2hex10($int, $in_hex) {
        $int = strtoupper(trim($int));
        // 內建函數優化常用進制
        if ($in_hex == 10) return $int;
        if ($in_hex == 2 && function_exists('bindec')) return bindec($int);
        if ($in_hex == 16 && function_exists('hexdec')) return hexdec($int);
        if ($in_hex == 8 && function_exists('octdec')) return octdec($int);

        $arr = [];
        $len = strlen($int);
        for ($i = 0; $i < $len; $i++) {
            array_unshift($arr, substr($int, $i, 1));  // 逆序入棧
        }
        $result = 0;
        foreach ($arr as $k => $v) {
            $val = array_search($v, self::$element);
            if ($val === false) return false;  // 非法字符
            $result += intval(pow($in_hex, $k) * $val);
        }
        return $result;
    }

    /** 十進制 → 任意進制(除基取餘法) */
    private function _conv_hex($hex_10, $out_hex) {
        $hex_10 = intval($hex_10);
        if ($out_hex == 10) return $hex_10;
        if ($out_hex == 2 && function_exists('decbin')) return decbin($hex_10);
        if ($out_hex == 16 && function_exists('dechex')) return dechex($hex_10);
        if ($out_hex == 8 && function_exists('decoct')) return decoct($hex_10);

        $arr = [];
        do {
            array_unshift($arr, $hex_10 % $out_hex);
            $hex_10 = intval($hex_10 / $out_hex);
        } while ($hex_10 > 0);  // 注意:原代碼 >1 有邊界bug,此處修正

        $result = '';
        foreach ($arr as $k) {
            $result .= self::$element[$k];
        }
        return $result;
    }
}

// 使用示例
$hex = new Hex();
echo $hex->conv('12345678901234567890', 16, 10);  // 大數十進制轉十六進制
echo $hex->conv('ZZ', 10, 36);                    // 36進制轉十進制
echo $hex->conv('1101', 10, 2);                   // 二進制轉十進制

核心優勢對比

特性base_convert()Hex 類
大數精度❌ 浮點運算,超 15 位丟失✅ 字符串/整數運算,無上限
字符集自定義❌ 固定 0-9a-z✅ 修改 $element 即可
進制範圍2-362-36(可擴展至 62+)
性能C 級極快PHP 級,大數優勢明顯

應用場景

  • 🔗 短網址 ID 生成(自增 ID → 62 進制)
  • 🎫 邀請碼/優惠碼生成(去除易混淆字符 0/O/I/l)
  • 🔐 簡易混淆加密(進制轉換 + 字符映射)
  • 📦 大整數存儲壓縮(十進制字符串 → 36 進制入庫)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved