PHP base_convert()函数

进制转换函数: base_convert() 函数用于在任意进制之间转换数字,支持从2到36进制的转换。

base_convert() 函数可以将一个数字从任意进制(2-36)转换为另一个任意进制(2-36)。该函数在处理不同进制的数字表示时非常有用,特别是在计算机科学和数学计算中。

函数语法

base_convert(string $num, int $from_base, int $to_base): string

参数说明

参数 类型 描述 必需
$num string 要转换的数字,以字符串形式表示
$from_base int 原始数字的进制(2-36)
$to_base int 目标进制(2-36)

返回值

返回转换后的数字,以字符串形式表示。如果无法转换,返回 0 或空字符串。

使用示例

示例1:基本进制转换

在不同进制之间进行基本转换:

<?php
// 二进制 ↔ 十进制
echo "二进制 '1010' 转换为十进制: " . base_convert('1010', 2, 10) . "\n"; // 10
echo "十进制 '10' 转换为二进制: " . base_convert('10', 10, 2) . "\n";     // 1010

// 八进制 ↔ 十进制
echo "八进制 '12' 转换为十进制: " . base_convert('12', 8, 10) . "\n";    // 10
echo "十进制 '10' 转换为八进制: " . base_convert('10', 10, 8) . "\n";    // 12

// 十六进制 ↔ 十进制
echo "十六进制 'A' 转换为十进制: " . base_convert('A', 16, 10) . "\n";   // 10
echo "十进制 '10' 转换为十六进制: " . base_convert('10', 10, 16) . "\n"; // A

// 十六进制 ↔ 二进制
echo "十六进制 'F' 转换为二进制: " . base_convert('F', 16, 2) . "\n";    // 1111
echo "二进制 '1111' 转换为十六进制: " . base_convert('1111', 2, 16) . "\n"; // F

// 复杂的转换
echo "十六进制 '1A3F' 转换为十进制: " . base_convert('1A3F', 16, 10) . "\n"; // 6719
echo "十进制 '6719' 转换为八进制: " . base_convert('6719', 10, 8) . "\n";   // 15077
echo "八进制 '15077' 转换为二进制: " . base_convert('15077', 8, 2) . "\n";  // 1101000111111

// 使用小写和大写字母
echo "十六进制 'abc' 转换为十进制: " . base_convert('abc', 16, 10) . "\n";  // 2748
echo "十六进制 'ABC' 转换为十进制: " . base_convert('ABC', 16, 10) . "\n";  // 2748
?>

示例2:高级进制转换类

创建一个高级的进制转换工具类:

<?php
// 高级进制转换类
class NumberBaseConverter {

    // 支持的进制字符集
    const CHARACTERS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

    // 检查进制是否有效(2-36)
    public static function isValidBase($base) {
        return is_numeric($base) && $base >= 2 && $base <= 36;
    }

    // 检查数字是否在指定进制中有效
    public static function isValidNumber($num, $base) {
        if (!self::isValidBase($base)) {
            return false;
        }

        $valid_chars = substr(self::CHARACTERS, 0, $base);

        // 检查每个字符是否有效
        $num = strtoupper((string)$num);
        for ($i = 0; $i < strlen($num); $i++) {
            if (strpos($valid_chars, $num[$i]) === false) {
                return false;
            }
        }

        return true;
    }

    // 安全的进制转换
    public static function safeConvert($num, $from_base, $to_base) {
        // 验证参数
        if (!self::isValidBase($from_base) || !self::isValidBase($to_base)) {
            throw new InvalidArgumentException("进制必须在2到36之间");
        }

        if (!self::isValidNumber($num, $from_base)) {
            throw new InvalidArgumentException("数字在{$from_base}进制中无效");
        }

        // 执行转换
        return base_convert(strtoupper($num), $from_base, $to_base);
    }

    // 批量转换
    public static function batchConvert(array $numbers, $from_base, $to_base) {
        $results = [];

        foreach ($numbers as $num) {
            try {
                $converted = self::safeConvert($num, $from_base, $to_base);
                $results[] = [
                    'original' => $num,
                    'converted' => $converted,
                    'status' => 'success'
                ];
            } catch (Exception $e) {
                $results[] = [
                    'original' => $num,
                    'converted' => null,
                    'status' => 'error',
                    'message' => $e->getMessage()
                ];
            }
        }

        return $results;
    }

    // 生成进制表
    public static function generateBaseTable($number, $max_base = 16) {
        if (!is_numeric($number) || $number < 0) {
            throw new InvalidArgumentException("数字必须是非负数");
        }

        $table = [];
        for ($base = 2; $base <= $max_base; $base++) {
            $table[$base] = base_convert($number, 10, $base);
        }

        return $table;
    }

    // 计算数字的位数
    public static function digitCount($num, $base) {
        $num = (string)$num;
        return strlen($num);
    }

    // 补零到指定长度
    public static function padZero($num, $length, $base = 10) {
        $result = strtoupper((string)$num);
        while (strlen($result) < $length) {
            $result = '0' . $result;
        }
        return $result;
    }
}

// 使用示例
echo "进制转换工具类演示:\n";

// 安全转换
try {
    echo "安全转换 'FF' 从16进制到10进制: ";
    echo NumberBaseConverter::safeConvert('FF', 16, 10) . "\n"; // 255

    echo "安全转换 '1010' 从2进制到16进制: ";
    echo NumberBaseConverter::safeConvert('1010', 2, 16) . "\n"; // A

    echo "安全转换 'Z' 从36进制到10进制: ";
    echo NumberBaseConverter::safeConvert('Z', 36, 10) . "\n"; // 35

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}

// 批量转换
echo "\n批量转换:\n";
$numbers = ['10', 'FF', '1010', '37'];
$results = NumberBaseConverter::batchConvert($numbers, 16, 10);

foreach ($results as $result) {
    echo "原始: " . $result['original'] . " → ";
    if ($result['status'] === 'success') {
        echo "转换: " . $result['converted'];
    } else {
        echo "错误: " . $result['message'];
    }
    echo "\n";
}

// 生成进制表
echo "\n数字 255 在不同进制下的表示:\n";
$table = NumberBaseConverter::generateBaseTable(255, 16);
foreach ($table as $base => $value) {
    echo "基数 " . str_pad($base, 2) . ": " . $value . "\n";
}

// 补零操作
echo "\n补零演示:\n";
echo "数字 'A' 补零到4位: " . NumberBaseConverter::padZero('A', 4, 16) . "\n";
echo "数字 '101' 补零到8位: " . NumberBaseConverter::padZero('101', 8, 2) . "\n";
echo "数字 '7' 补零到3位: " . NumberBaseConverter::padZero('7', 3, 10) . "\n";
?>

示例3:计算机科学应用

在计算机科学和编程中的应用:

<?php
// IP地址与数字转换
class IPAddressConverter {

    // IPv4地址转换为十进制数字
    public static function ipv4ToDecimal($ip) {
        // 验证IP地址格式
        if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
            throw new InvalidArgumentException("无效的IPv4地址");
        }

        // 将IP地址拆分为四个部分
        $parts = explode('.', $ip);

        // 计算十进制值
        $decimal = 0;
        for ($i = 0; $i < 4; $i++) {
            $decimal += $parts[$i] * pow(256, 3 - $i);
        }

        return $decimal;
    }

    // 十进制数字转换为IPv4地址
    public static function decimalToIpv4($decimal) {
        if (!is_numeric($decimal) || $decimal < 0 || $decimal > 4294967295) {
            throw new InvalidArgumentException("无效的十进制IP值");
        }

        $parts = [];
        for ($i = 3; $i >= 0; $i--) {
            $parts[] = floor($decimal / pow(256, $i));
            $decimal %= pow(256, $i);
        }

        return implode('.', $parts);
    }

    // IPv4地址转换为十六进制
    public static function ipv4ToHex($ip) {
        $decimal = self::ipv4ToDecimal($ip);
        return strtoupper(dechex($decimal));
    }

    // 十六进制转换为IPv4地址
    public static function hexToIpv4($hex) {
        $decimal = hexdec($hex);
        return self::decimalToIpv4($decimal);
    }

    // IPv4地址转换为二进制
    public static function ipv4ToBinary($ip) {
        $decimal = self::ipv4ToDecimal($ip);
        return decbin($decimal);
    }

    // 二进制转换为IPv4地址
    public static function binaryToIpv4($binary) {
        $decimal = bindec($binary);
        return self::decimalToIpv4($decimal);
    }
}

// 使用示例
echo "IP地址转换:\n";

$ip = '192.168.1.1';
echo "原始IP地址: $ip\n";

try {
    $decimal = IPAddressConverter::ipv4ToDecimal($ip);
    echo "十进制表示: $decimal\n";

    $hex = IPAddressConverter::ipv4ToHex($ip);
    echo "十六进制表示: 0x$hex\n";

    $binary = IPAddressConverter::ipv4ToBinary($ip);
    echo "二进制表示: $binary\n";

    // 反转换
    $ip_from_decimal = IPAddressConverter::decimalToIpv4($decimal);
    echo "从十进制恢复: $ip_from_decimal\n";

    $ip_from_hex = IPAddressConverter::hexToIpv4($hex);
    echo "从十六进制恢复: $ip_from_hex\n";

    $ip_from_binary = IPAddressConverter::binaryToIpv4($binary);
    echo "从二进制恢复: $ip_from_binary\n";

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}

// 颜色代码转换
echo "\n颜色代码转换:\n";
class ColorConverter {

    // RGB转十六进制
    public static function rgbToHex($r, $g, $b) {
        self::validateRGB($r, $g, $b);

        $hex_r = str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
        $hex_g = str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
        $hex_b = str_pad(dechex($b), 2, '0', STR_PAD_LEFT);

        return '#' . strtoupper($hex_r . $hex_g . $hex_b);
    }

    // 十六进制转RGB
    public static function hexToRgb($hex) {
        // 移除#号
        $hex = ltrim($hex, '#');

        // 验证长度
        if (strlen($hex) != 6 && strlen($hex) != 3) {
            throw new InvalidArgumentException("无效的十六进制颜色代码");
        }

        // 处理3位简写
        if (strlen($hex) == 3) {
            $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
        }

        // 转换为十进制
        $r = hexdec(substr($hex, 0, 2));
        $g = hexdec(substr($hex, 2, 2));
        $b = hexdec(substr($hex, 4, 2));

        return ['r' => $r, 'g' => $g, 'b' => $b];
    }

    // RGB转不同进制
    public static function rgbToDifferentBases($r, $g, $b) {
        self::validateRGB($r, $g, $b);

        return [
            'decimal' => "$r,$g,$b",
            'hex' => self::rgbToHex($r, $g, $b),
            'binary' => decbin($r) . ',' . decbin($g) . ',' . decbin($b),
            'octal' => decoct($r) . ',' . decoct($g) . ',' . decoct($b)
        ];
    }

    private static function validateRGB($r, $g, $b) {
        if ($r < 0 || $r > 255 || $g < 0 || $g > 255 || $b < 0 || $b > 255) {
            throw new InvalidArgumentException("RGB值必须在0-255之间");
        }
    }
}

// 颜色转换示例
$r = 255; $g = 127; $b = 0; // 橙色
echo "RGB颜色: R=$r, G=$g, B=$b\n";

try {
    $hex = ColorConverter::rgbToHex($r, $g, $b);
    echo "十六进制: $hex\n";

    $rgb = ColorConverter::hexToRgb($hex);
    echo "从十六进制恢复: R={$rgb['r']}, G={$rgb['g']}, B={$rgb['b']}\n";

    $all_bases = ColorConverter::rgbToDifferentBases($r, $g, $b);
    echo "不同进制表示:\n";
    foreach ($all_bases as $base => $value) {
        echo "  $base: $value\n";
    }

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}

// 内存地址转换
echo "\n内存地址转换:\n";
function formatMemoryAddress($address, $format = 'hex') {
    $address = (int)$address;

    switch (strtolower($format)) {
        case 'hex':
            return '0x' . strtoupper(dechex($address));
        case 'binary':
            return '0b' . decbin($address);
        case 'octal':
            return '0' . decoct($address);
        case 'decimal':
            return (string)$address;
        default:
            throw new InvalidArgumentException("不支持的格式: $format");
    }
}

$memory_address = 4096; // 4KB地址
echo "内存地址 4096:\n";
echo "十六进制: " . formatMemoryAddress($memory_address, 'hex') . "\n";
echo "二进制: " . formatMemoryAddress($memory_address, 'binary') . "\n";
echo "八进制: " . formatMemoryAddress($memory_address, 'octal') . "\n";
echo "十进制: " . formatMemoryAddress($memory_address, 'decimal') . "\n";
?>

示例4:错误处理和边界情况

处理base_convert()函数的错误和边界情况:

<?php
// 安全的base_convert包装器
class SafeBaseConvert {

    // 安全转换,包含完整错误处理
    public static function convert($num, $from_base, $to_base) {
        // 输入验证
        if (!is_string($num) && !is_numeric($num)) {
            throw new InvalidArgumentException("数字必须是字符串或数字");
        }

        $num = (string)$num;

        // 检查进制范围
        if (!self::isValidBase($from_base) || !self::isValidBase($to_base)) {
            throw new InvalidArgumentException("进制必须在2到36之间");
        }

        // 空字符串处理
        if ($num === '') {
            return '0';
        }

        // 负号处理(base_convert不支持负数)
        $is_negative = false;
        if ($num[0] === '-') {
            $is_negative = true;
            $num = substr($num, 1);

            if ($num === '') {
                return '0';
            }
        }

        // 验证数字在源进制中是否有效
        if (!self::isValidNumberForBase($num, $from_base)) {
            throw new InvalidArgumentException("数字'$num'在{$from_base}进制中无效");
        }

        // 执行转换
        $result = base_convert($num, $from_base, $to_base);

        // 处理转换失败
        if ($result === false || $result === '') {
            throw new RuntimeException("转换失败");
        }

        // 恢复负号
        if ($is_negative && $result !== '0') {
            $result = '-' . $result;
        }

        return $result;
    }

    // 验证进制是否有效
    private static function isValidBase($base) {
        return is_numeric($base) && $base >= 2 && $base <= 36;
    }

    // 验证数字在指定进制中是否有效
    private static function isValidNumberForBase($num, $base) {
        $num = strtoupper($num);
        $valid_chars = substr('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', 0, $base);

        for ($i = 0; $i < strlen($num); $i++) {
            if (strpos($valid_chars, $num[$i]) === false) {
                return false;
            }
        }

        return true;
    }

    // 测试各种边界情况
    public static function testBoundaryCases() {
        $test_cases = [
            // [数字, 源进制, 目标进制, 期望结果/期望异常]
            ['1010', 2, 10, '10'],
            ['A', 16, 10, '10'],
            ['0', 10, 2, '0'],
            ['', 10, 2, '0'],  // 空字符串
            ['-10', 10, 2, '-1010'],
            ['-0', 10, 2, '0'],
            ['FF', 16, 10, '255'],
            ['ZZ', 36, 10, '1295'],
            ['100', 10, 37, null],  // 无效进制
            ['2', 2, 10, null],     // 数字在二进制中无效
            ['G', 16, 10, null],    // 数字在十六进制中无效
            ['999999999999999999999999999', 10, 2, '110010011100010111010111000111001010111111010000101111111111111111111111111111111111111111'], // 大数
        ];

        echo "边界情况测试:\n";
        echo str_repeat('-', 80) . "\n";

        foreach ($test_cases as $case) {
            list($num, $from, $to, $expected) = $case;

            echo "测试: '$num' ($from → $to): ";

            try {
                $result = self::convert($num, $from, $to);

                if ($expected === null) {
                    echo "✗ 期望异常但得到了结果: $result\n";
                } elseif ($result === $expected) {
                    echo "✓ 成功: $result\n";
                } else {
                    echo "✗ 失败: 期望 $expected, 得到 $result\n";
                }

            } catch (Exception $e) {
                if ($expected === null) {
                    echo "✓ 成功抛出异常: " . $e->getMessage() . "\n";
                } else {
                    echo "✗ 意外异常: " . $e->getMessage() . "\n";
                }
            }
        }
    }

    // 性能测试
    public static function performanceTest($iterations = 10000) {
        echo "\n性能测试 ($iterations 次迭代):\n";

        $start = microtime(true);
        for ($i = 0; $i < $iterations; $i++) {
            base_convert('FFFFFFFF', 16, 2);
        }
        $native_time = microtime(true) - $start;

        $start = microtime(true);
        for ($i = 0; $i < $iterations; $i++) {
            self::convert('FFFFFFFF', 16, 2);
        }
        $safe_time = microtime(true) - $start;

        echo "原生 base_convert: " . round($native_time * 1000, 2) . " ms\n";
        echo "SafeBaseConvert: " . round($safe_time * 1000, 2) . " ms\n";
        echo "开销: " . round((($safe_time - $native_time) / $native_time * 100), 2) . "%\n";
    }
}

// 运行测试
try {
    SafeBaseConvert::testBoundaryCases();
    SafeBaseConvert::performanceTest(1000);

} catch (Exception $e) {
    echo "测试错误: " . $e->getMessage() . "\n";
}

// 处理大数字
echo "\n大数字处理:\n";

// PHP整数限制
$large_numbers = [
    '999999999999999999999',  // 超过PHP整数范围
    'FFFFFFFFFFFFFFFF',        // 16进制大数
    '11111111111111111111111111111111111111111',  // 二进制大数
];

foreach ($large_numbers as $num) {
    echo "数字: $num\n";

    // 尝试不同的转换
    try {
        // 十六进制转十进制
        if (ctype_xdigit(str_replace(['-', '+'], '', $num))) {
            $dec = base_convert($num, 16, 10);
            echo "  十六进制→十进制: $dec\n";
        }

        // 十进制转二进制
        $bin = base_convert($num, 10, 2);
        echo "  十进制→二进制: " . substr($bin, 0, 50) . "...\n";

    } catch (Exception $e) {
        echo "  错误: " . $e->getMessage() . "\n";
    }
}

// 浮点数处理(base_convert不支持浮点数)
echo "\n浮点数处理:\n";
$float_numbers = ['10.5', '3.14', '0.1'];

foreach ($float_numbers as $num) {
    echo "浮点数: $num\n";

    // 分离整数和小数部分
    $parts = explode('.', $num);
    $integer_part = $parts[0];
    $fraction_part = isset($parts[1]) ? $parts[1] : '';

    try {
        // 转换整数部分
        $int_bin = base_convert($integer_part, 10, 2);
        echo "  整数部分(10→2): $int_bin\n";

        // 转换小数部分(简化处理)
        if ($fraction_part !== '') {
            echo "  小数部分: 需要特殊处理(base_convert不支持)\n";
        }

    } catch (Exception $e) {
        echo "  错误: " . $e->getMessage() . "\n";
    }
}
?>

示例5:实际应用场景

在实际开发中的应用场景:

<?php
// 加密和解密应用
class SimpleCrypto {

    // 使用base_convert进行简单编码
    public static function encodeWithBase($text, $base = 16) {
        $encoded = '';

        for ($i = 0; $i < strlen($text); $i++) {
            $char_code = ord($text[$i]);
            $encoded .= base_convert($char_code, 10, $base) . ':';
        }

        return rtrim($encoded, ':');
    }

    // 解码
    public static function decodeFromBase($encoded, $base = 16) {
        $parts = explode(':', $encoded);
        $text = '';

        foreach ($parts as $part) {
            if ($part !== '') {
                $char_code = (int)base_convert($part, $base, 10);
                $text .= chr($char_code);
            }
        }

        return $text;
    }

    // 生成随机字符串(指定进制)
    public static function generateRandomString($length, $base = 16) {
        $chars = substr('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', 0, $base);
        $result = '';

        for ($i = 0; $i < $length; $i++) {
            $result .= $chars[random_int(0, $base - 1)];
        }

        return $result;
    }
}

// 使用示例
echo "简单加密/编码:\n";
$text = "Hello World!";
echo "原始文本: $text\n";

$encoded = SimpleCrypto::encodeWithBase($text, 16);
echo "编码 (base16): $encoded\n";

$decoded = SimpleCrypto::decodeFromBase($encoded, 16);
echo "解码: $decoded\n";

// 不同进制编码
$bases = [2, 8, 16, 32];
foreach ($bases as $base) {
    $encoded = SimpleCrypto::encodeWithBase($text, $base);
    echo "Base $base 编码: " . substr($encoded, 0, 50) . "...\n";
}

// 生成随机字符串
echo "\n随机字符串生成:\n";
for ($base = 2; $base <= 16; $base *= 2) {
    $random = SimpleCrypto::generateRandomString(10, $base);
    echo "Base $base 随机字符串: $random\n";
}

// 文件权限表示(Unix风格)
echo "\n文件权限转换 (Unix风格):\n";
class FilePermissions {

    // 八进制权限转字符串表示
    public static function octalToSymbolic($octal) {
        $permissions = [
            '0' => '---',
            '1' => '--x',
            '2' => '-w-',
            '3' => '-wx',
            '4' => 'r--',
            '5' => 'r-x',
            '6' => 'rw-',
            '7' => 'rwx'
        ];

        $octal_str = (string)$octal;
        $symbolic = '';

        for ($i = 0; $i < strlen($octal_str); $i++) {
            $digit = $octal_str[$i];
            if (isset($permissions[$digit])) {
                $symbolic .= $permissions[$digit];
            }
        }

        return $symbolic;
    }

    // 字符串表示转八进制
    public static function symbolicToOctal($symbolic) {
        $permissions = [
            '---' => '0',
            '--x' => '1',
            '-w-' => '2',
            '-wx' => '3',
            'r--' => '4',
            'r-x' => '5',
            'rw-' => '6',
            'rwx' => '7'
        ];

        $octal = '';

        for ($i = 0; $i < strlen($symbolic); $i += 3) {
            $chunk = substr($symbolic, $i, 3);
            if (isset($permissions[$chunk])) {
                $octal .= $permissions[$chunk];
            }
        }

        return $octal;
    }

    // 权限检查和转换
    public static function convertPermissions($input, $output_format = 'both') {
        $result = [];

        // 判断输入格式
        if (is_numeric($input)) {
            // 八进制输入
            $octal = decoct($input); // 转换为八进制字符串
            $result['octal'] = $octal;
            $result['symbolic'] = self::octalToSymbolic($octal);
        } elseif (preg_match('/^[rwsx-]{9}$/', $input)) {
            // 符号输入
            $result['symbolic'] = $input;
            $result['octal'] = self::symbolicToOctal($input);
        } else {
            throw new InvalidArgumentException("无效的权限格式");
        }

        // 添加二进制表示
        $result['binary'] = base_convert($result['octal'], 8, 2);

        // 添加十进制表示
        $result['decimal'] = base_convert($result['octal'], 8, 10);

        return $result;
    }
}

// 文件权限示例
$permission_examples = [0755, 0644, 'rwxr-xr-x', 'rw-r--r--'];

foreach ($permission_examples as $perm) {
    echo "权限: $perm\n";

    try {
        $converted = FilePermissions::convertPermissions($perm);
        echo "  八进制: 0" . $converted['octal'] . "\n";
        echo "  符号表示: " . $converted['symbolic'] . "\n";
        echo "  二进制: " . str_pad($converted['binary'], 9, '0', STR_PAD_LEFT) . "\n";
        echo "  十进制: " . $converted['decimal'] . "\n";
    } catch (Exception $e) {
        echo "  错误: " . $e->getMessage() . "\n";
    }
    echo "\n";
}

// URL短链接生成(使用base_convert)
echo "URL短链接生成:\n";
class URLShortener {

    // 使用base_convert生成短码
    public static function generateShortCode($url, $length = 6) {
        // 生成哈希
        $hash = md5($url);

        // 取哈希的一部分转换为高进制
        $part = substr($hash, 0, 8);
        $decimal = hexdec($part);

        // 转换为62进制(数字+大小写字母)
        $short_code = self::base62_encode($decimal);

        // 截取指定长度
        return substr($short_code, 0, $length);
    }

    // 自定义base62编码
    private static function base62_encode($num) {
        $chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
        $base = 62;
        $result = '';

        while ($num > 0) {
            $remainder = $num % $base;
            $result = $chars[$remainder] . $result;
            $num = intdiv($num, $base);
        }

        return $result ?: '0';
    }

    // 使用base_convert(最大36进制)
    public static function generateShortCode36($url, $length = 8) {
        $hash = md5($url);
        $part = substr($hash, 0, 8);
        $decimal = hexdec($part);

        // 转换为36进制
        $code = base_convert($decimal, 10, 36);

        return str_pad($code, $length, '0', STR_PAD_LEFT);
    }
}

// 生成短链接
$urls = [
    'https://www.example.com/page1',
    'https://www.example.com/page2',
    'https://www.example.com/page3'
];

foreach ($urls as $url) {
    $short_code = URLShortener::generateShortCode36($url, 8);
    echo "URL: " . substr($url, 0, 30) . "...\n";
    echo "短码 (base36): $short_code\n\n";
}

// 数据验证码生成
echo "数据验证码生成:\n";
function generateChecksum($data, $base = 16) {
    // 简单校验和计算
    $checksum = 0;

    for ($i = 0; $i < strlen($data); $i++) {
        $checksum += ord($data[$i]);
    }

    // 转换为指定进制
    return base_convert($checksum, 10, $base);
}

$test_data = "Hello, World!";
$checksums = [];

for ($base = 2; $base <= 36; $base *= 2) {
    $checksum = generateChecksum($test_data, $base);
    $checksums[$base] = $checksum;
    echo "Base $base 校验和: $checksum\n";
}
?>

数学原理

进制转换原理

N进制表示:一个N进制数可以表示为:

aₖaₖ₋₁...a₁a₀ = aₖ×Nᵏ + aₖ₋₁×Nᵏ⁻¹ + ... + a₁×N¹ + a₀×N⁰

进制字符集:

  • 2进制:0-1
  • 8进制:0-7
  • 10进制:0-9
  • 16进制:0-9, A-F
  • 36进制:0-9, A-Z
转换算法

十进制转N进制:

  1. 将十进制数除以N,记录余数
  2. 用商继续除以N,直到商为0
  3. 将余数倒序排列

N进制转十进制:

按权展开求和:∑(aᵢ × Nⁱ)

大数处理:PHP使用字符串表示大数,避免整数溢出

常见进制对照表

十进制 二进制 八进制 十六进制 32进制
0 0 0 0 0
10 1010 12 A A
255 11111111 377 FF 7V
1000 1111101000 1750 3E8 V8
65535 1111111111111111 177777 FFFF 1VVV

注意事项

重要提醒
  • 字符串参数:第一个参数必须是字符串,数字会自动转换为字符串
  • 进制范围:只支持2到36进制,超出范围会返回0或错误
  • 大小写敏感:字母不区分大小写,但输出通常是小写
  • 负数处理:不支持负数,负数会被当作正数处理
  • 精度问题:对于极大数字可能存在精度损失
  • 浮点数:不支持浮点数,小数部分会被忽略

相关函数

bindec()

二进制转十进制

decbin()

十进制转二进制

dechex()

十进制转十六进制

decoct()

十进制转八进制

hexdec()

十六进制转十进制

octdec()

八进制转十进制

常见问题

base_convert() 函数支持的最大进制是36进制。进制系统使用以下字符集:
  • 0-9:数字0到9
  • A-Z:字母A到Z(不区分大小写)
因此总共36个字符(10个数字 + 26个字母)。如果需要更高的进制,需要自己实现转换函数。

主要原因:

  1. PHP整数限制:PHP的整数类型有最大限制(PHP_INT_MAX),超出范围会转换为浮点数,可能丢失精度
  2. 浮点数精度:对于极大数字,PHP可能使用浮点数表示,导致精度损失
  3. 算法限制:转换算法在处理极大数字时可能存在数值稳定性问题

解决方案:

  • 使用BCMath或GMP扩展进行高精度计算
  • 对于极大数字,考虑分段处理
  • 使用专门的数学库

需要自己实现转换函数。基本思路:

function custom_base_convert($num, $from_base, $to_base) {
    // 定义字符集(可以扩展到62进制或更高)
    $charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

    // 转换为十进制(中间表示)
    $decimal = '0';
    for ($i = 0; $i < strlen($num); $i++) {
        $char = $num[$i];
        $value = strpos($charset, $char);
        $decimal = bcadd(bcmul($decimal, $from_base), $value);
    }

    // 转换为目标进制
    $result = '';
    while (bccomp($decimal, '0') > 0) {
        $remainder = bcmod($decimal, $to_base);
        $result = $charset[$remainder] . $result;
        $decimal = bcdiv($decimal, $to_base, 0);
    }

    return $result ?: '0';
}

注意:这个示例使用了BCMath函数来处理大数,确保精度。